证明三个子表达式的两个简化情况的等价性相对容易:
a && (b && c) --> a && bc // bc is a shorthand for b && c
在这里,a 将首先被评估。如果为假,短路将阻止bc 的评估。如果为真,将评估bc,即评估b && c。如果b 为假,则不会评估c。
(a && b) && c --> ab && c // ab is a shorthand for a && b
在这里,ab 将首先被评估。 (即首先评估a && b。如果a 为假,短路将阻止b 的评估。否则,ab 产生b。)如果ab 为假,c 获胜'不被评估。
现在,如果您更喜欢证据而不是证明,可以查看以下 C 代码的汇编输出:
int a(), b(), c(), d();
void e()
{
a() && b() && c() && d();
}
void f()
{
a() && (b() && (c() && d()));
}
void g()
{
(a() && b()) && (c() && d());
}
void h()
{
((a() && b()) && c()) && d();
}
(我使用 C 代码而不是 C++ 代码来防止名称混淆。)
为e 生成程序集:
_e:
// ... enter ...
call _a
testl %eax, %eax
je L1
call _b
testl %eax, %eax
je L1
call _c
testl %eax, %eax
je L1
call _d
testl %eax, %eax
nop
L1:
// ... leave ...
为f 生成的程序集:
_f:
// ... enter ...
call _a
testl %eax, %eax
je L4
call _b
testl %eax, %eax
je L4
call _c
testl %eax, %eax
je L4
call _d
testl %eax, %eax
nop
L4:
// ... leave ...
为g生成程序集:
_g:
// ... enter ...
call _a
testl %eax, %eax
je L7
call _b
testl %eax, %eax
je L7
call _c
testl %eax, %eax
je L7
call _d
testl %eax, %eax
nop
L7:
// ... leave ...
为h生成程序集:
_h:
// ... enter ...
call _a
testl %eax, %eax
je L10
call _b
testl %eax, %eax
je L10
call _c
testl %eax, %eax
je L10
call _d
testl %eax, %eax
nop
L10:
// ... leave ...
如您所见,除了标签之外,生成的汇编代码完全相同。