这是a discussion的后续内容,我认为这应该是一个问题。
基本上,这是未定义的结果吗?
int x;
int y = 1 || x;
这里有两个“常识”论点:
x
的价值如何,y
的值都应为1
。x
。但反驳的是,我们有一个涉及未初始化变量的表达式,所以所有的赌注都是关闭的(理论上)。
更一般地说,如果未初始化变量的值不可能影响表达式的结果,那么它是否“安全”? e.g:
int x;
int y = x - x;
通常的免责声明:当然,我并不是主张编写这样的代码。
答案 0 :(得分:8)
在C中,使用具有自动存储持续时间的对象的值是不确定的行为,而它是不确定的。 (J.2,提供信息)但是对于具有自动存储持续时间的变量来说,保持不确定的值是可以的。
表达式只能在计算时使用其值,并且根据6.5.12(逻辑OR运算符),如果第一个操作数将不等于0,则不计算第二个操作数(更不用说使用其值)。 / p>
答案 1 :(得分:6)
免责声明: 我认为这个问题也适用于C ++。显然它只适用于C语言。我不会说C-standardese,但我相信我的答案也适用于C,尽管使用不同的术语
int x;
int y = 1 || x;
定义明确,因为x根本没有被评估 - 保证了||的短路评估。
int x;
int y = x - x;
调用未定义的行为,因为x被评估并且 发生左值到右值的转换 。如果没有进行转换,则行为将被明确定义,例如:
int x;
int* y = &x;
int z = &x - &x;
此处还评估了x,但没有进行左值到右值的转换,因此定义了它。
答案 2 :(得分:2)
关于y = x - x;
,要记住的一个最坏情况是未初始化的变量可能包含陷阱值。
您不能依赖优化器的存在来意识到x - x
实际上并不依赖于x
的值,因此当然允许实现使用{的值{1}}在评估x
时,它在抽象机器中使用。
因此,如果它是陷阱值,则会出现硬件错误或陷阱时实现的任何错误。无论如何,UB。
我记得我使用过的一个系统增加了对不确定值行为的额外保证。它声明使用不确定的值不会爆炸,但也不要求表现为该值是该类型的任何实际值。因此,x - x
将导致另一个不确定的值,不一定是0.这实际上 less 比捕获更有用,因为它存储编程错误以供以后使用时最不期望它,但是AFAIK完全符合标准,因为行为不是由标准定义的。
答案 3 :(得分:1)
基本上,这是未定义的结果吗?
int x; int y = 1 || x;
Nopes! x
永远不会使用 / 评估。
int y = x - x;
调用UB。