C++ “AND” 评估 - 标准保证?[复制]

C++ 'AND' evaluation - standard guaranteed? [duplicate]

提问人:Luchian Grigore 提问时间:10/2/2011 最后编辑:CommunityLuchian Grigore 更新时间:10/2/2011 访问量:226

问:

这个问题在这里已经有答案了:
12年前关闭。

可能的重复:
短路评估的安全问题

该标准对计算表达式有什么看法 - 它是否保证参数的计算将首先停止?&&false

例如:

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

如果 ?f()p == NULL

另外,评估的顺序是否保证是子句中的出现顺序?

优化器可能会更改以下内容:

int x;
Foo* p;
//...
if ( p->doSomethingReallyExpensive() && x == 3 )
{
    //....
}

到它首先评估的形式?还是总是先执行真正昂贵的功能?x==3

我知道在大多数编译器(可能是所有编译器)上,评估在遇到第一个编译器后就会停止,但是标准对此有何说明?false

C++语言

评论


答:

3赞 Nawaz 10/2/2011 #1

该标准对计算 & 表达式有什么看法 - 它是否保证参数的计算将停止在第一个错误?

是的。这就是所谓的短路。

另外,评估的顺序是否保证是子句中的出现顺序?

是的。从左到右。表达式短路之前不计算操作数。

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

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

其实以上两点是我这里解决方案的关键点:

1赞 C. K. Young 10/2/2011 #2

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

3赞 Foo Bah 10/2/2011 #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++ 标准中有一个等效的语句

0赞 K-ballo 10/2/2011 #4

该标准对计算 & 表达式有什么看法 - 它是否保证参数的计算将停止在第一个错误?

另外,评估的顺序是否保证是子句中的出现顺序?

5.14/1. 与 &、&& 不同,保证从左到右的计算:如果第一个操作数为假,则不计算第二个操作数。

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

优化器可能会更改以下内容: if ( p->doSomethingReallyExpensive() && x == 3 ) 到它首先计算 x==3 的形式?

优化器可能会决定先求值,因为它是一个没有副作用的表达式,如果未被 修改,甚至可以在已经返回 false 之后求值它。但是,可见行为保证是前面指定的:从左到右评估和短路。这意味着,虽然可以首先计算并返回 false,但实现仍然必须计算 。x == 3xp->doSomethingReallyExpensive()p->doSomethingReallyExpensive()x == 3p->doSomethingReallyExpensive()