“如果”论证评估顺序?

发布于 2024-12-12 12:03:09 字数 143 浏览 2 评论 0原文

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

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

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

(我用的是VS2008)

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

is there any possibility to evaluate arguments from right to left(b -> a)?

if "yes", what influences the evaluation order?

(i'm using VS2008)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

少钕鈤記 2024-12-19 12:03:09

对于 C++,只有少数运算符可以保证计算顺序

  • operator && 首先计算左操作数,如果该值在逻辑上为 false,则它会避免计算正确的操作数。典型的用法是例如 if (x > 0 && k/x < limit) ... ,它可以避免被零除的问题。

  • operator || 首先评估左操作数,如果该值在逻辑上为 true,则它会避免评估右操作数。例如,if (overwrite_files ||确认("文件已存在,覆盖?")) ... 当设置 overwrite_files 标志时,不会询问确认。

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

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

对于所有其他运算符,未指定求值顺序。

情况实际上更糟,因为不是没有指定顺序,而是表达式根本没有“顺序”,例如,

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

函数可能会按 hgkxf< 的顺序调用/code> (这有点令人不安,因为 << 运算符的心智模型以某种方式传达了顺序性的概念,但实际上仅按照结果放入流中的顺序尊重顺序,而不是按照顺序按结果顺序计算*)。

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

另请注意,&&||, 的保证仅对预定义运算符有效。如果您为您的类型重载这些运算符,那么在这种情况下它们将像正常的函数调用一样,并且操作数的求值顺序将是未指定的。

(*)自 C++17 以来的更改

C++17 引入了一些关于计算顺序的额外临时特定保证(例如在左移运算符 << 中)。有关所有详细信息,请参阅https://stackoverflow.com/a/38501596/320726

With C++ there are only a few operators that guarantee the evaluation order

  • operator && evaluates left operand first and if the value is logically false then it avoids evaluating the right operand. Typical use is for example if (x > 0 && k/x < limit) ... that avoids division by zero problems.

  • operator || evaluates left operand first and if the value is logically true then it avoids evaluating the right operand. For example if (overwrite_files || confirm("File existing, overwrite?")) ... will not ask confirmation when the flag overwrite_files is set.

  • operator , evaluates left operand first and then right operand anyway, returning the value of right operand. This operator is not used very often. Note that commas between parameters in a function call are not comma operators and the order of evaluation is not guaranteed.

  • The ternary operator x?y:z evaluates x first, and then depending on the logical value of the result evaluates either only y or only z.

For all other operators the order of evaluation is not specified.

The situation is actually worse because it's not that the order is not specified, but that there is not even an "order" for the expression at all, and for example in

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

it's possible that functions will be called in the order h-g-k-x-f (this is a bit disturbing because the mental model of << operator conveys somehow the idea of sequentiality but in reality respects the sequence only in the order results are put on the stream and not in the order the results are computed*).

Obviously the value dependencies in the expression may introduce some order guarantee; for example in the above expression it's guaranteed that both k() and h() will be called before x(...) because the return values from both are needed to call x (C++ is not lazy).

Note also that the guarantees for &&, || and , are valid only for predefined operators. If you overload those operators for your types they will be in that case like normal function calls and the order of evaluation of the operands will be unspecified.

(*)Changes since C++17

C++17 introduced some extra ad-hoc specific guarantees about evaluation order (for example in the left-shift operator <<). For all the details see https://stackoverflow.com/a/38501596/320726

╰◇生如夏花灿烂 2024-12-19 12:03:09

评估顺序由标准指定,为从左到右。最左边的表达式始终首先使用 && 子句进行计算。

如果您希望首先对 b 进行求值:

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

如果两个参数都是方法,并且您希望对它们进行求值,而不管其结果如何:

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

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

The evaluation order is specified by the standard and is left-to-right. The left-most expression will always be evaluated first with the && clause.

If you want b to be evaluated first:

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

If both arguments are methods and you want both of them to be evaluated regardless of their result:

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

if ( ra && rb )
{
  //do something
}
滥情稳全场 2024-12-19 12:03:09

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

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

In this case, since you're using &&, a will always be evaluated first because the result is used to determine whether or not to short-circuit the expression.

If a returns false, then b is not allowed to evaluate at all.

七分※倦醒 2024-12-19 12:03:09

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

请阅读此处,了解规则集的更详尽解释:
订单评估

Every value computation and side effect of the first (left) argument of the built-in logical AND operator && and the built-in logical OR operator || is sequenced before every value computation and side effect of the second (right) argument.

Read here for a more exhaustive explanation of the rules set:
order evaluation

贱贱哒 2024-12-19 12:03:09

它将从左到右进行评估,并在可能的情况下短路评估(例如,如果 a 评估为 false,则不会评估 b)。

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

It will evaluate from left to right and short-circuit the evaluation if it can (e.g. if a evaluates to false it won't evaluate b).

If you care about the order they are evaluated in you just need to specify them in the desired order of evaluation in your if statement.

鹊巢 2024-12-19 12:03:09

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

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

如果 afalse,则不会评估 b

如果您希望首先计算 b,并且仅在 b 为 true 时才计算 a,只需以相反的方式编写表达式即可:

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

The built-in && operator always evaluates its left operand first. For example:

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

If a is false, then b will not be evaluated.

If you want b to be evaluated first, and a only if b is true, simply write the expression the other way around:

if (b && a)
{
   //block of code
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文