短路和括号 [英] short circuiting and parenthesis
问题描述
在处理单个短路运算符时,我如何对子表达式进行分组?
a& b&&& ; d
:
a&&& (b&(c& d))
(a&& b)&& (c& d)
((a& b)&& c)&&上述表达式是否等同?>解决方案对于三个子表达式的两个简化情况,证明等价是相对容易的:
a&& (b& c) - > a&& bc // bc是b&& c
这里将首先评估
a
。如果为假,短路将阻止bc
的评估。如果为真,则将评估bc
,即b&& c
将被计算。如果b
为false,则不会评估c
。(a&& b)&& c - > ab&&& c // ab是一个&& b
这里将首先评估
ab
。 (a& b
首先被评估。如果a
为假,短路将阻止评估b
。否则,ab
产生b
。ab
为false,将不评估c
。
< hr>
现在,如果你喜欢证据证明,你可以看看下面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:
// ...输入...
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:
// ...输入...
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:
// ...离开...
正如你所看到的,除了标签,生成的汇编代码是完全相同的。
Does it matter how I group subexpressions when dealing with a single short-circuiting operator?
a && b && c && d a && (b && (c && d)) (a && b) && (c && d) ((a && b) && c) && d
Are the above expressions equivalent?
解决方案It is relatively easy to prove the equivalence for two simplified cases of three subexpressions:
a && (b && c) --> a && bc // bc is a shorthand for b && c
Here,
a
will be evaluated first. If it is false, short circuiting will prevent the evaluation ofbc
. If it is true,bc
will be evaluated, that is,b && c
will be evaluated. Ifb
is false,c
won't be evaluated.(a && b) && c --> ab && c // ab is a shorthand for a && b
Here,
ab
will be evaluated first. (That isa && b
is evaluated first. Ifa
is false, short circuiting will prevent the evaluation ofb
. Otherwise,ab
yieldsb
.) Ifab
is false,c
won't be evaluated.
Now, if you prefer evidence to proof, you can look at the assembly output of the following C code:
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(); }
(I used C code as opposed to C++ code to prevent name mangling.)
generated assembly for
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 ...
generated assembly for
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 ...
generated assembly for
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 ...
generated assembly for
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 ...
As you can see, apart from labels, the generated assembly code is completely identical.
这篇关于短路和括号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!