标准对评估&&
表达式有何评价 - 它是否保证参数评估将在第一个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}}之后评估停止了,但是标准对它有什么看法?
答案 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
。