简体   繁体   English

使用数组作为在C ++中有效的条件表达式?

[英]Is using 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 like this: buffer decays to a pointer, then a pointer is compared against null. Visual C ++ 10解释如下: buffer衰减到指针,然后指针与null进行比较。 When this is compiled with /O2 the check gets eliminated and the code gets equivalent to just return 1; 当用/ O2编译它时,检查被消除,代码等同于return 1; .

Is the code above valid? 以上代码有效吗? Does Visual C++ compile it right (I mean the decaying part, not the optimization)? Visual C ++是否正确编译(我的意思是衰减部分,而不是优化)?

C++11, 6.4/4: C ++ 11,6.4 / 4:

The value of a condition that is an expression is the value of the expression, contextually converted to bool for statements other than switch; 作为表达式的条件的值是表达式的值,对于除switch之外的语句,上下文转换为bool; if that conversion is ill-formed, the program is ill-formed. 如果转换形成不良,该计划就是格式错误。

So the standard says that the compiler has to perform any implicit conversions at its disposal to convert the array to a boolean. 因此标准规定编译器必须执行任何隐式转换,以将数组转换为布尔值。 Decaying the array to pointer and converting the pointer to boolean with a test against against equality to null is one way to do that, so yes the program is well-defined and yes it does produce the correct result -- obviously, since the array is allocated on the stack, the pointer it decays to can never be equal to the null pointer. 将数组衰减到指针并将指针转换为boolean并使用针对null的测试转换为null是一种方法,所以是的,程序是明确定义的,是的,它确实产生了正确的结果 - 显然,因为数组是在堆栈上分配,它衰减的指针永远不能等于空指针。

Update: As to why this chain of two conversions is followed: 更新:至于为什么要遵循这两个转换链:

C++11, 4.2/1: C ++ 11,4.2 / 1:

An lvalue or rvalue of type “array of NT” or “array of unknown bound of T” can be converted to a prvalue of type “pointer to T”. 可以将“数组的NT”或“未知的T的数组”类型的左值或右值转换为“指向T的指针”的prvalue。 The result is a pointer to the first element of the array. 结果是指向数组的第一个元素的指针。

So, the only legal conversion from an array type is to a pointer to element type. 因此,从数组类型的唯一合法转换是指向元素类型的指针。 There is no choice in the first step. 第一步没有选择。

C++11, 4.12/1: C ++ 11,4.12 / 1:

A prvalue of arithmetic, unscoped enumeration, pointer , or pointer to member type can be converted to a prvalue of type bool . 算术,无范围枚举, 指针或指向成员类型的指针的prvalue可以转换为bool类型的prvalue。 A zero value, null pointer value, or null member pointer value is converted to false ; 零值,空指针值或空成员指针值转换为false ; any other value is converted to true . 任何其他值都转换为true A prvalue of type std::nullptr_t can be converted to a prvalue of type bool ; 类型为std::nullptr_t的prvalue可以转换为bool类型的prvalue; the resulting value is false . 结果值为false

There is an implicit conversion directly from bare pointer to boolean; 直接从裸指针到布尔值的转换; so the compiler picks that as the second step because it allows the desired result (conversion to boolean) to be immediately reached. 所以编译器选择它作为第二步,因为它允许立即达到所需的结果(转换为布尔值)。

Yes, the conversion from an array type to bool is well-defined by the standard conversions. 是的,标准转换可以很好地定义从数组类型到bool的转换。 Quoting C++11, 4/1 (with the relevant conversions highlighted): 引用C ++ 11,4 / 1(突出显示相关转换):

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 promotions, floating point promotion, integral conversions, floating point conversions, floating-integral conversions, pointer conversions, pointer to member conversions, and boolean conversions . - 来自以下集合的零或一次转换:整数促销,浮点促销,积分转换,浮点转换,浮点积分转换,指针转换,成员转换指针和布尔转换

— Zero or one qualification conversion. - 零或一个资格转换。

A standard conversion sequence will be applied to an expression if necessary to convert it to a required destination type. 如果需要,将标准转换序列应用于表达式,以将其转换为所需的目标类型。

Yes. 是。

if( buffer ) means: check if buffer is not NULL . if( buffer )表示:检查buffer是否为NULL An array variable points to the start of the array (unless you move it) and is equivalent to a pointer. 数组变量指向数组的开头(除非你移动它)并且等同于指针。

The optimization just returns 1 because that buffer is allocated on the stack, so it definitely has a value (pointer to the location on the stack), so it's always true. 优化只返回1,因为buffer是在堆栈上分配的,所以它肯定有一个值(指向堆栈上位置的指针),所以它总是如此。

You said it yourself : 你自己说的:

buffer decays to a pointer 缓冲区衰减到指针

Since the array is on the stack, it can not be NULL (unless something goes wrong, like stack smashing). 由于数组在堆栈上,因此不能为NULL(除非出现问题,例如堆栈粉碎)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM