Uses an array as a conditional expression valid in C ++?

I have this code:

int main() { char buffer[10]; if( buffer ) { return 1; } return 0; } 

which Visual C ++ 10 interprets as follows: buffer decays to a pointer, then the pointer is compared to zero. When this is compiled with / O 2, the check will be eliminated, and the code will be equivalent only to return 1; .

Is the code above valid? Does Visual C ++ compile it correctly (I mean the decaying part, not the optimization)?

+4
source share
4 answers

Yes, the conversion from array to bool well defined by standard conversions. Citation C ++ 11, 4/1 (with highlighted corresponding transformations):

A standard conversion sequence is a sequence of standard conversions in the following order:

- Zero or one conversion from the following set: lvalue-to-rvalue conversion, array to pointer conversion, and function to pointer conversion.

- Zero or one conversion from the following set: integral shares, floating point promotion, integral conversion, floating point conversion, floating integral conversion, pointer conversion, pointer to membership conversion and logical conversion .

- Zero or one qualification conversion.

The standard conversion sequence will be applied to the expression, if necessary, to convert it to the desired destination type.

+3
source

C ++ 11, 6.4 / 4:

The value of a condition that is an expression is the value of an expression contextually converted to bool for statements other than a switch; if this transformation is poorly formed, the program is poorly formed.

Thus, the standard says that the compiler must perform any implicit conversions at its disposal in order to convert the array to logical. Expanding the array to a pointer and converting the pointer to boolean with a test against equality to zero is one way to do this, so yes, the program is well defined and yes, it gives the correct result - obviously, since the array is allocated on the stack, the pointer that it splits up, can never be equal to a null pointer.

Update: Regarding this chain of two transformations:

C ++ 11, 4.2 / 1:

An array of NT or an array of unknown bounds of T lvalue or rvalue type can be converted to a pointer to T type prvalue. The result is a pointer to the first element of the array.

So, the only legal conversion from an array type is a pointer to an element type. There is no choice at the first stage.

C ++ 11, 4.12 / 1:

Arithmetic value, unlisted enumeration, pointer or a member type pointer can be converted to a prvalue of type bool . Zero value, null pointer value or null element pointer value is converted to false ; any other value is converted to true . A value of type std::nullptr_t can be converted to prvalue of type bool ; The resulting value is false .

There is an implicit conversion directly from the bare pointer to boolean; therefore, the compiler chooses this as the second step, because it allows you to immediately get the desired result (conversion to logical).

+7
source

Yes.

if( buffer ) means: check, not buffer NULL . An array variable points to the beginning of the array (unless you move it) and is equivalent to a pointer.

Optimization simply returns 1 because buffer is allocated on the stack, so it definitely matters (a pointer to the location on the stack), so it is always right.

+1
source

You yourself said:

buffer splits to pointer

Since the array is on the stack, it cannot be NULL (if something is wrong, like breaking a stack).

0
source

Source: https://habr.com/ru/post/1387193/


All Articles