C++ 编译器优化和短路评估

标签 c++ compilation short-circuiting

<分区>

这是我的代码:

b = f() || b;

f() 函数有副作用,必须始终执行。通常,只有正确的操作数可以短路,这段代码应该可以工作。但恐怕有些编译器会颠倒这两个操作数,因为短路函数评估比简单的变量评估更有效。我知道 g++ -O3 会破坏一些规范,但我不知道这段代码是否会受到影响。

那么,我的代码没有风险吗?

我知道Is short-circuiting logical operators mandated? And evaluation order?但我的问题是关于编译器优化,我不知道它们不能违反标准(即使这很奇怪)。

最佳答案

But I am afraid some compilators reverse the two operands

这些表达式必须从左到右求值。这包含在有关运算符 &&||?, 的标准中。他们特别提到顺序,以及强制执行的顺序点。

§5.14.1(逻辑与)

The && operator groups left-to-right. The operands are both contextually converted to bool (Clause 4). The result is true if both operands are true and false otherwise. Unlike &, && guarantees left-to-right evaluation: the second operand is not evaluated if the first operand is false.

§5.15.1(逻辑或)

The || operator groups left-to-right. The operands are both contextually converted to bool (Clause 4). It returns true if either of its operands is true, and false otherwise. Unlike |, || guarantees left-to-right evaluation; moreover, the second operand is not evaluated if the first operand evaluates to true.

§5.16.1(条件运算符)

Conditional expressions group right-to-left. The first expression is contextually converted to bool (Clause 4). It is evaluated and if it is true, the result of the conditional expression is the value of the second expression, otherwise that of the third expression. Only one of the second and third expressions is evaluated. Every value computation and side effect associated with the first expression is sequenced before every value computation and side effect associated with the second or third expression.

§5.19.1(逗号运算符)

The comma operator groups left-to-right. A pair of expressions separated by a comma is evaluated left-to-right; the left expression is a discarded value expression (Clause 5). Every value computation and side effect associated with the left expression is sequenced before every value computation and side effect associated with the right expression. The type and value of the result are the type and value of the right operand; the result is of the same value category as its right operand, and is a bit-field if its right operand is a glvalue and a bit-field. If the value of the right operand is a temporary (12.2), the result is that temporary.

关于您对违反此顺序的优化的担忧,没有编译器不允许更改顺序。编译器必须首先(尝试)遵循标准。 然后他们可以尝试使您的代码更快。他们可能不会仅仅为了性能而违反标准。这破坏了拥有标准的整个前提。

关于C++ 编译器优化和短路评估,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31052979/

相关文章:

c - 如何在C中编译时确定宏值?

c++ - 调用带有编译错误的 C++ 方法

c++ - 无法从 Windows 注册表中查询值

c++ - 用一个线程做一个部分,用多个线程做一个for循环

c++ - 无法捕获 C++ 异常

python - 有没有办法知道 .pyc 文件是由哪个 Python 版本编译的?

java - 使用逻辑或 (||) 测试 if 语句的覆盖率 - 对于 Java 的短路,JaCoCo 希望我覆盖的第四个条件是什么?

javascript - 为什么 `false && true || true` 评估为真?

java - 什么(在规范中)保证“非短路逻辑运算符实际上不会短路?”

c++ - 有没有办法将标准输出设置为二进制模式?