C和C ++操作数解析顺序

时间:2016-03-10 09:26:11

标签: c++ c language-lawyer

很多时候,我看到(有时会写)与此示例类似的代码:

int a=0, b=2;
if( a && (b=func())!=0 ) {
//...

问题是:标准是否保证这些陈述?

  1. b将不会被触及(并保留值2
  2. func()将不会被称为
  3. 反之亦然,如果我们写if( func()!=0 && a ) - 是否会调用标准保证func()

    我对定义这是合法的特定标准段感兴趣。

    UPD:我的拼写错误,从int a=1更改为int a=0

5 个答案:

答案 0 :(得分:4)

来自C-90标准。

  

6.5.13逻辑AND运算符

     

...

     

4与按位二进制&操作员,&&运营商保证从左到右的评估;   在评估第一个操作数后有一个序列点。如果是第一个操作数   比较等于0,不评估第二个操作数。

与Logical OR运算符类似。

答案 1 :(得分:4)

确切的问题;

  

问题是:标准是否保证这些陈述?

更新的问题;给定a=0。如果a==0,则是,短路评估将启动,func()将不会被调用;第二个操作数不会被评估。

如果a=1(原来是),则相反;将调用func() - a1因此为“true”,因此评估第二个操作数(它是逻辑AND),b将更改。如果运算符为||(逻辑或),则短路评估将启动,func()将不会被调用。

  

反之亦然,如果我们写if( func()!=0 && a ) - 是否会调用标准保证func()

是的,始终会评估第一个操作数。

是的,C ++保证短路评估;

§5.14逻辑AND运算符

  

1 &&运算符组从左到右。操作数都在上下文中转换为bool(第4条)。如果两个操作数都为真,则结果为true,否则为false。与&不同,&&保证从左到右的评估:如果第一个操作数为假,则不评估第二个操作数。

     

2结果是一个布尔。如果计算第二个表达式,则在每个值计算和与第二个表达式相关的副作用之前,对与第一个表达式关联的每个值计算和副作用进行排序。

§5.15逻辑OR运算符

  

1 ||运算符组从左到右。操作数都在上下文中转换为bool(第4条)。如果其任一操作数为true,则返回true,否则返回false。与|不同,||保证从左到右的评估;此外,如果第一个操作数的计算结果为true,则不计算第二个操作数。

     

2结果是一个布尔。如果计算第二个表达式,则在每个值计算和与第二个表达式相关的副作用之前,对与第一个表达式关联的每个值计算和副作用进行排序。

C的相应引号是;

§6.5.13逻辑AND运算符

  

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

§6.5.14逻辑OR运算符

  

4与按位|运算符不同,||运算符保证从左到右的评估;如果计算第二个操作数,则在第一个和第二个操作数的计算之间存在一个序列点。如果第一个操作数将不等于0,则不计算第二个操作数。

答案 2 :(得分:2)

该标准保证&&序列中的语句从左到右进行评估,并且只要其中一个语句的计算结果为false,就不会评估其右侧的语句。< / p>

答案 3 :(得分:2)

&&运算符要求两个操作数都为true。如果第一个操作数的计算结果为false,则不会计算第二个操作数。但是因为a是1,它被认为是真的,并且第二个表达式(操作数)被计算。因此调用func()并将其分配给b然后b的结果测试为非零。

答案 4 :(得分:-1)

  

问题是:标准是否保证这些陈述?

     

b将不被触及(并保持值2)

     不会调用

func()

不,实际上他们两个都错了。因为它的运算符&&所以在这种特殊情况下不能应用快捷逻辑。

如果您将其更改为||,那么您的陈述是正确的 - 只有这样,第一个操作数(在这种情况下为a = 1)的评估才足够,其余部分将被忽略。

当问题变为a = 0然后是,两个陈述都是正确且有保证的。