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

时间:2015-06-25 14:17:15

标签: c++ compilation short-circuiting

这是我的代码:

b = f() || b;

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

那么,我的代码是无风险的吗?

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

2 个答案:

答案 0 :(得分:12)

  

但我担心有些编译器可以反转这两个操作数

这些表达必须从左到右进行评估。有关运营商&&||?,的标准涵盖了这一点。他们特别提到了顺序,以及强制序列点。

§5.14.1(逻辑与)

  

&&运算符组从左到右。操作数都在上下文中转换为bool(第4条)。如果两个操作数都为真,则结果为true,否则为false。 &不同,&&保证从左到右评估:如果第一个操作数为false,则不评估第二个操作数。

§5.15.1(逻辑或)

  

||运算符组从左到右。操作数都在上下文中转换为bool(第4条)。如果其任一操作数为true,则返回true,否则返回false。 |不同,||保证从左到右的评估;此外,如果第一个操作数的计算结果为true,则不计算第二个操作数。

§5.16.1(条件运算符)

  

条件表达式从右到左分组。第一个表达式在上下文中转换为bool(第4条)。它被评估,如果是,则条件表达式的结果是第二个表达式的值,   否则第三个表达。仅评估第二和第三表达式中的一个。与第一个表达式相关的每个值计算和副作用在每个值计算之前排序   与第二或第三个表达相关的副作用。

§5.19.1(逗号运算符)

  

逗号运算符从左到右分组。用逗号分隔的一对表达式从左到右进行评估;左表达式是丢弃的值   表达(第5条)。与左表达相关联的每个值计算和副作用在每个值计算和与右表达式相关的副作用之前排序。结果的类型和值是右操作数的类型和值;结果具有相同的值类别   作为右操作数,如果右操作数是glvalue和bit-field,则是一个位字段。如果右操作数的值是临时值(12.2),则结果是临时值。

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

答案 1 :(得分:6)

标准明确规定优化代码应该表现为" as-if"它只是编写的代码,只要您只依赖于标准行为。

由于标准要求从左到右评估布尔语句,因此没有(合规)优化可以改变评估顺序。