4

如果我有这样的情况:

if (X && Y) {}

编译器会检查Y是否X为假吗?它依赖于编译器吗?

4

5 回答 5

10

在 C 和大多数其他语言中,短路评估是有保证的。所以Y只有在X评估为真时才被评估。

这同样适用于X || Y- 在这种情况下,仅在评估为 falseY时才评估。X

有关提及并保证此行为的 C 规范的参考,请参阅Mike 的回答。

于 2013-03-26T13:27:54.063 回答
7

C 规范(6.5.13)为您阐明了这一点:

4 与按位二进制 & 运算符不同,&& 运算符保证从左到右的求值;如果计算第二个操作数,则在第一个和第二个操作数的计算之间存在一个序列点。如果第一个操作数比较等于 0,则不计算第二个操作数。

所以 C 语言本身定义了 if X == 0thenY不会被检查。

于 2013-03-26T13:45:08.747 回答
3

Y仅当是时才X检查true

如果X为假则Y不会被检查

顺便说一句,检查是在执行运行时完成的,而不是在编译阶段

于 2013-03-26T13:28:49.680 回答
1

&&||强制从左到右评估。如果计算第二个操作数,两者都将在第一个和第二个操作数之间引入一个序列点。如果表达式的结果可以单独从第一个操作数确定,则两者都不会计算第二个操作数。IOW, for X && Y,Y如果X为假则不会被评估,而 for X || Y,Y如果X为真则不会被评估。

请注意,优先级不影响评估顺序;给定一个表达式,例如X || Y && Z,之前Y && Z不会计算X,即使&&它的优先级高于||. X首先被评估;如果结果为 0(假),则Y进行评估。如果该结果为非零(真),则Z进行评估。

这是在语言标准(2011 版,在线草案)的第 6.5.13 和 6.5.14 节中定义的,因此它不依赖于编译器。

于 2013-03-26T13:45:03.550 回答
0

如果Y有副作用,或者如果访问它可能是未定义的行为(例如错误的指针取消引用),那么编译器必须确保Y除非X评估为真,否则不会评估它。但是,如果两者都X没有Y副作用并且编译器知道对它们的访问是明确定义的,它可能会选择以两种访问都发生的方式进行优化。

于 2013-03-26T13:45:08.660 回答