C++优化If语句

3
考虑以下语句:

 C a, b; //C contains c1, c2 and c3 all integers

if(a.c1==b.c1 && a.c2 == b.c2) {
     a.c3=b.c3;
 }

这个语句将被优化为以下内容:

 if(a.c1 == b.c1) {
    if(a.c2 == b.c2) {
       a.c3=b.c3;
    }
 }

据我所知,C++编译器不执行这种操作,因为它可能会产生副作用。但这些是内置类型。
  • 标准中是否有相关内容?
  • 如果这是编译器特定的,主流编译器(如MS、GNU、Intel)是否都在执行此操作?

11
实际上,这种“优化”需要使用该语言。 - Eric Lippert
4个回答

9

可以的。下面是代码片段:

C a, b; //C contains c1, c2 and c3 all integers
if(a.c1==b.c1 && a.c2 == b.c2)
{
    a.c3=b.c3;
}

将被“优化”为以下内容(或等效内容):
if(a.c1 == b.c1)
{
    if(a.c2 == b.c2)
    {
        a.c3=b.c3
    }
}

这不是因为优化而是因为C++标准要求短路求值。因此合理符合C++标准的编译器应该能够进行短路求值。

C++标准中没有明确说明某些布尔运算符会被短路求值,但可以从规则中推断出来。

ISO/IEC C++ Standard 14882 §5.14 Logical AND operator [expr.log.and]

logical-and-expression:
    inclusive-or-expression
    logical-and-expression && inclusive-or-expression
  1. The && operator groups left-to-right. The operands are both implicitly converted to type 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.

|| 运算符的规则类似:

ISO/IEC C++ Standard 14882 §5.15 Logical OR operator [expr.log.or]

logical-or-expression:
    logical-and-expression
    logical-or-expression || logical-and-expression
  1. The || operator groups left-to-right. The operands are both implicitly 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.

条件运算符 ?

ISO/IEC C++标准 14882 §5.16 条件运算符 [expr.cond] 条件表达式: 逻辑或表达式 逻辑或表达式 ? 表达式1 : 赋值表达式

  1. 条件表达式从右到左进行分组。第一个表达式会隐式转换为bool类型(见第4条)。如果它的值为true,则条件表达式的结果是第二个表达式的值;否则为第三个表达式的值。第一个表达式产生的所有副作用(临时对象除外,详见12.2节)都会在第二个或第三个表达式求值之前发生。只有第二个和第三个表达式中的一个会被求值。

3

标准5.14 / 1 :

&& 运算符从左到右分组。操作数都会被隐式转换为 bool 类型(第4条款)。 如果两个操作数都是 true,则结果为 true,否则为 false。与 & 不同的是,&& 保证从左到右进行求值:如果第一个操作数为 false,则不会对第二个操作数求值。


0

C++使用短路求值。因此,在某种程度上它会以这种方式工作。

它实际上并不会以那种方式评估和优化代码,但它将评估为相当于汇编代码的等效形式。


1
我真的希望短路评估成为一些东西。 - jsj

0

&& 运算符是短路运算。换句话说,如果 a.c1 == b.c1 的结果不为真,那么 a.c2 == b.c2 将不会被计算。

这与您描述的解决方案类似,但它是 C++ 语言的一部分(并且比显式嵌套 if 语句更容易阅读)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接