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

C++ 'AND' evaluation - standard guaranteed?

本文关键字:标准 AND 评估 C++      更新时间:2023-10-16

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

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

例如:

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

如果p == NULL,是否保证不会调用f()

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

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

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

到它首先评估x==3的表单?还是它总是先执行真正昂贵的函数?

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

标准对评估&表达式-它是否保证参数的求值将在第一个false时停止?

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

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

是的。从左到右。表达式短路之前的操作数不会得到求值。

int a = 0;
int b = 10;
if ( a != 0 && (b=100)) {}
cout << b << endl; //prints 10, not 100

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

  • 不使用条件语句和三元运算符求C中三个数的最大值

在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++标准中有一个等价的语句

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

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

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

5.14/1.不同于&amp&保证从左到右求值:如果第一个操作数为false,则不求值第二个操作数。

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

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

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