C ++'AND'评估 - 标准保证?

时间:2011-10-01 17:31:22

标签: c++

  

可能重复:
  Safety concerns about short circuit evaluation

标准对评估&&表达式有何评价 - 它是否保证参数评估将在第一个false停止?

E.g:

Foo* p;
//....
if ( p && p->f() )
{
    //do something
}

f()p == NULL保证在int x; Foo* p; //... if ( p->doSomethingReallyExpensive() && x == 3 ) { //.... }

时不被调用

此外,评估的顺序是否保证是条款中的外观顺序?

优化器可能会改变:

x==3

首先评估false的表单?或者它会一直执行真正昂贵的功能吗?

我知道在大多数编译器(可能是所有编译器)上,在遇到第一个{{1}}之后评估停止了,但是标准对它有什么看法?

4 个答案:

答案 0 :(得分:3)

  

该标准对评估&& amp;表达式 - 它是否保证参数的评估将在第一个假的时候停止?

是。这被称为短路。

  

此外,评估的顺序是否保证是条款中的外观顺序?

是。从左到右。表达式短路的操作数不会被评估。

int a = 0;
int b = 10;
if ( a != 0 && (b=100)) {}

cout << b << endl; //prints 10, not 100

事实上,以上两点是我解决方案的关键点:

答案 1 :(得分:3)

在ANSI C标准3.3.13:

Unlike the bitwise binary & operator, the && operator guarantees
left-to-right evaluation; there is a sequence point after the
evaluation of the first operand.  If the first operand compares equal
to 0, the second operand is not evaluated.

C ++标准中有一个等效的陈述

答案 2 :(得分:1)

&&(和||)建立序列点。因此,左侧的表达式将在右侧之前进行评估。另外,是的,如果左侧是假/真(对于&& / ||),则不评估右侧。

答案 3 :(得分:0)

  

该标准对评估&amp;&amp; amp;表达式 - 它是否保证参数的评估将在第一个假的时候停止?

     

此外,评估的顺序是否保证是条款中的外观顺序?

5.14 / 1。不像&amp;,&amp;&amp;保证从左到右的评估:如果第一个操作数为假,则不评估第二个操作数。

这仅适用于标准&amp;&amp;运算符,用户定义的operator &&重载没有这个保证,它们的行为类似于常规函数调用语义。

  

优化器可能会改变:   if(p-> doSomethingReallyExpensive()&amp;&amp; x == 3)   到一个首先评估x == 3的形式?

优化程序可能会首先评估x == 3,因为如果x没有修改p->doSomethingReallyExpensive(),它就是一个没有相关副作用的表达式,甚至可以在{{1}之后对其进行评估已经返回false。但是,可见行为保证是先前指定的:从左到右评估和短路。这意味着虽然可以先评估p->doSomethingReallyExpensive()并返回false,但实现仍需要评估x == 3