“IF”论证评估顺序?

时间:2011-10-28 05:26:05

标签: c++ if-statement operator-precedence

if(a && b)
{
  do something;
}

是否有可能从右到左评估参数(b - > a)?

如果“是”,影响评估顺序的是什么?

(我正在使用VS2008)

6 个答案:

答案 0 :(得分:55)

使用C ++,只有少数运算符可以保证评估顺序

  • operator &&首先评估左操作数,如果值是逻辑false,则它避免评估右操作数。典型的用法是if (x > 0 && k/x < limit) ...,它可以避免零除问题。

  • operator ||首先评估左操作数,如果值是逻辑true,则它避免评估右操作数。例如,if (overwrite_files || confirm("File existing, overwrite?")) ...在设置标记overwrite_files时不会要求确认。

  • operator ,首先评估左操作数,然后评估右操作数,返回右操作数的值。不经常使用此运算符。请注意,函数调用中参数之间的逗号是不是逗号运算符,并且无法保证评估顺序。

  • 三元运算符x?y:z首先评估x,然后根据结果的逻辑值评估y或仅评估z

对于所有其他运营商,未指定评估顺序。

情况实际上更糟糕,因为并不是指定了订单,而是根本没有表达式的“订单”,例如在

std::cout << f() << g() << x(k(), h());

可能会按照h-g-k-x-f的顺序调用函数(这有点令人不安,因为<<运算符的心理模型以某种方式表达了顺序性的概念,但实际上只考虑了序列的顺序订单结果将放在流上,而不是按计算结果的顺序排列。)

显然,表达式中的值依赖性可能会引入一些顺序保证;例如,在上面的表达式中,保证在k()之前调用h()x(...),因为调用x需要两者的返回值。

另请注意,&&||,的保证仅对预定义的运算符有效。如果你为你的类型重载那些运算符,它们就像普通函数调用一样,并且操作数的评估顺序将是未指定的。

答案 1 :(得分:43)

评估订单由标准指定,并且为left-to-right。最左边的表达式将始终使用&&子句进行评估。

如果您希望首先评估b

if(b && a)
{
  //do something
}

如果两个参数都是方法,并且您希望无论结果如何都要对它们进行评估:

bool rb = b();
bool ra = a();

if ( ra && rb )
{
  //do something
}

答案 2 :(得分:7)

在这种情况下,由于您正在使用&&,因此将始终首先评估a,因为结果用于确定是否将表达式短路。

如果a返回false,则根本不允许b进行评估。

答案 3 :(得分:4)

  

内置逻辑AND运算符的第一个(左)参数的每个值计算和副作用&amp;&amp;和内置的逻辑OR运算符||在每个值计算和第二个(右)参数的副作用之前排序。

请阅读此处以获得有关规则集的更详尽解释: order evaluation

答案 4 :(得分:2)

它将从左到右进行评估,如果可以,则将评估短路(例如,如果评估结果为假,则不会评估b)。

如果您关心他们的评估顺序,您只需要在if语句中按照所需的评估顺序指定它们。

答案 5 :(得分:1)

内置&&运算符始终首先计算其左操作数。例如:

if (a && b)
{
   //block of code
}

如果afalse,则不会评估b

如果您希望首先评估b,而仅在a为真时评估b,则只需反过来编写表达式:

if (b && a)
{
   //block of code
}