请考虑以下声明:
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;
}
}
AFAIK,C ++编译器不执行此类操作,因为它可能有副作用。但这些都是内置类型。
答案 0 :(得分:8)
是。以下代码段:
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 ++标准需要 short-circuit evaluation。因此,合理的符合标准的C ++编译器应该能够使其短路。
C ++标准中没有一个地方明确声明某些布尔运算符是短路的。这是从规则中隐含的:
ISO / IEC C ++标准14882§5.14逻辑AND运算符[expr.log.and]
logical-and-expression: inclusive-or-expression logical-and-expression && inclusive-or-expression
- 醇>
&&
运算符组从左到右。操作数都是 隐式转换为类型bool
(第4条)。结果是true
if 除此之外,两个操作数都是true
和false
。 与&
不同,&&
保证从左到右的评估:第二个操作数不是 评估第一个操作数是false
。
||
运算符的规则类似:
ISO / IEC C ++标准14882§5.15逻辑OR运算符[expr.log.or]
logical-or-expression: logical-and-expression logical-or-expression || logical-and-expression
- 醇>
||
运算符组从左到右。操作数都是 隐式转换为bool
(第4条)。如果有,则返回true
其操作数为true
,否则为false
。 与|
不同,||
保证从左到右的评估;而且,第二个操作数是 如果第一个操作数的计算结果为true
,则不进行评估。
条件?
运算符:
ISO / IEC C ++标准14882§5.16条件运算符[expr.cond] 条件表达式: 逻辑或表达 逻辑或表达?表达式:赋值表达式
- 条件表达式从右到左分组。第一个表达 隐式转换为
醇>bool
(第4条)。它被评估,如果 它是true
,条件表达式的结果是值 第二个表达式,否则表达第三个表达式。所有 除了破坏之外,第一个表达的副作用 临时(12.2)发生在第二或第三个表达之前 评估。 第二个和第三个表达式中只有一个是 评价。强>
答案 1 :(得分:3)
标准5.14 / 1:
&&操作员组从左到右。操作数都隐式转换为bool类型(第4节)。 如果两个操作数都为真,则结果为true,否则为false。不像&,&&保证从左到右 评估:如果第一个操作数为假,则不评估第二个操作数。
答案 2 :(得分:0)
C ++使用shirt-circuit evaluation。所以,在某种程度上它将以这种方式工作。
我实际上并没有以这种方式评估和优化代码,但它将在汇编代码中进行评估。
答案 3 :(得分:0)
&&运营商正在短路。换句话说,如果a.c1 == b.c1无法评估为真,那么甚至不会评估a.c2 == b.c2。
它类似于您描述的解决方案,但它是C ++语言的一部分(并且比显式键入嵌套的if语句更容易阅读。)