短路和括号 [英] short circuiting and parenthesis

查看:166
本文介绍了短路和括号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在处理单个短路运算符时,我如何对子表达式进行分组?

  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 of bc. If it is true, bc will be evaluated, that is, b && c will be evaluated. If b 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 is a && b is evaluated first. If a is false, short circuiting will prevent the evaluation of b. Otherwise, ab yields b.) If ab 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆