如果我有这样的条件:
if (X && Y) {}
如果Y
为假,编译器会检查X
吗?它是编译器依赖的吗?
答案 0 :(得分:10)
在C和most other languages短路评估得到保证。因此,Y
仅在X
评估为真时才会被评估。
同样适用于X || Y
- 在这种情况下Y
仅在X
评估为false时进行评估。
请参阅Mike's answer以获取对C规范的引用,其中提及并保证了此行为。
答案 1 :(得分:7)
C规范(6.5.13)为您澄清了这一点:
4与按位二进制&操作员,&& operator 保证从左到右的评估; 如果计算第二个操作数,则在评估之间存在一个序列点 第一和第二个操作数。 如果第一个操作数比较等于0,则第二个操作数 操作数未被评估。
因此,C语言本身定义了如果X == 0
,则不会检查Y
。
答案 2 :(得分:3)
仅当Y
为X
true
如果X
为false,则不会检查Y
BTW 检查在执行运行时完成,而不是在编译阶段完成
答案 3 :(得分:1)
&&
和||
强制从左到右评估。如果计算第二个操作数,则两者都将在第一个和第二个操作数之间引入一个序列点。如果可以仅从第一个操作数确定表达式的结果,则不会评估第二个操作数。 IOW,对于X && Y
,如果Y
为false,则不会评估X
,而对于X || Y
,如果Y
则不会评估X
是真的。
请注意,优先顺序不会影响评估顺序;给定X || Y && Z
之类的表达式,Y && Z
将 not 在X
之前进行评估,即使&&
的优先级高于||
。首先评估X
;如果结果为0(false),则评估Y
。如果该结果为非零(true),则评估Z
。
这在language standard(2011版,在线草案)的6.5.13和6.5.14节中定义,因此它不依赖于编译器。
答案 4 :(得分:0)
如果Y
有副作用,或者访问它可能是未定义的行为(例如错误的指针取消引用),那么编译器必须确保不评估Y
,除非X
已评估为真。但是,如果X
和Y
都没有副作用,并且编译器知道对它们的访问是明确定义的,那么它可能会选择以两种访问方式进行优化。