我有这段代码:
int main()
{
char buffer[10];
if( buffer ) {
return 1;
}
return 0;
}
Visual C ++ 10解释如下:buffer
衰减到指针,然后将指针与null进行比较。当使用/ O2编译它时,检查将被删除,代码仅相当于return 1;
。
以上代码有效吗? Visual C ++是否正确编译(我的意思是衰减部分,而不是优化)?
答案 0 :(得分:7)
C ++ 11,6.4 / 4:
作为表达式的条件的值是的值 表达式,上下文转换为bool以外的语句 开关;如果这种转换形成不良,那么该计划就会形成不良。
因此标准规定编译器必须执行任何隐式转换,以将数组转换为布尔值。将数组衰减到指针并将指针转换为boolean并使用针对null的测试转换为null是一种方法,所以是的,程序是明确定义的,是的,它确实产生了正确的结果 - 显然,因为数组是在堆栈上分配,它衰减的指针永远不会等于空指针。
更新关于为什么遵循这两个转换链:
C ++ 11,4.2 / 1:
“N T数组”或“未知数组的数组”的左值或右值 T“可以转换为”指向T“的prvalue类型。结果 是指向数组第一个元素的指针。
因此,从数组类型的唯一合法转换是指向元素类型的指针。第一步没有选择。
C ++ 11,4.12 / 1:
算术,无范围枚举,指针或指针的prvalue 成员类型可以转换为
bool
类型的prvalue。零 转换value,null指针值或null成员指针值 到false
;任何其他值都将转换为true
。一个类型的prvaluestd::nullptr_t
可以转换为bool
类型的prvalue;该 结果值为false
。
直接从裸指针到boolean有一个隐式转换;所以编译器选择它作为第二步,因为它允许立即达到所需的结果(转换为布尔值)。
答案 1 :(得分:3)
是的,标准转换可以很好地定义从数组类型到bool
的转换。引用C ++ 11,4 / 1(突出显示相关转换):
标准转换序列是以下标准转换序列 顺序:
- 来自以下集合的零次或一次转换:左值到右值转换,数组到指针转换, 和函数到指针的转换。
- 来自以下集合的零或一次转换:整数促销,浮点促销,积分 转换,浮点转换,浮点积分转换,指针转换,指针指向 成员转化和布尔转换。
- 零或一个资格转换。
如果需要,标准转换序列将应用于表达式,以将其转换为必需的 目的地类型。
答案 2 :(得分:1)
是
if( buffer )
表示:检查buffer
是否不是NULL
。数组变量指向数组的开头(除非你移动它)并且等同于指针。
优化只返回1,因为buffer
在堆栈上分配,所以它肯定有一个值(指向堆栈上位置的指针),所以它总是正确的。
答案 3 :(得分:0)
你自己说:
缓冲区衰减到指针
由于数组在堆栈上,因此不能为NULL(除非出现问题,例如堆栈粉碎)。