是否有任何保证,if-else if-else if-else
块的ifs按照它们的编写顺序进行测试。
我问的是因为我经常尝试通过最频繁的案例来首先优化我的代码,并且我想知道编译器完成的某些优化是否会改变测试if的顺序。
所以,如果我正在写这样的代码:
if (cond1) // First if (for the case I have the most often)
{
doSomething1();
}
else if (cond2) // Second if (for the second case I have the most often)
{
doSomething2();
}
else if (cond3) // Third if (for the third case I have the most often)
{
doSomething3();
}
else
{
doElse();
}
是否有任何保证在编译后(发布),第一个if将被测试,然后是第二个if,然后是第三个if(如果没有条件为真,则最后执行else) 的
我知道在调试时,ifs按照我编写的顺序执行,但是当程序编译发布时它会保持正确(我主要使用g ++和visual studio的最新版本)。
此外,由于条件可能会对环境产生影响(如if (i=a)
或if(myfunction())
),它们应该按照书面执行,但我想知道我是否遗漏了编译器可以进行的一些优化do,这会改变测试ifs的顺序。特别是,如果条件没有这样的副作用:
void test(int a)
{
if (a == 1)
{
doSomething1();
}
else if (a == 2)
{
doSomething1();
}
else if (a == 3)
{
doSomething1();
}
else
{
doSomething1();
}
}
答案 0 :(得分:7)
有没有保证在编译之后(发布),第一个if将被测试,然后是第二个if,然后是第三个if(如果没有条件为真,则最后执行else)。
是的,但不是专门针对if语句,所有(单线程)代码。
C ++代码从头到尾自上而下执行。唯一的情况可能不是这种情况,当你进行异步调用或让多个线程同时调用相同的代码时。
答案 1 :(得分:6)
来自C ++ 03,§6.4选择陈述:
1
selection-statement: if ( condition ) statement if ( condition ) statement else statement switch ( condition ) statement[...] 如果selection-statement中的子语句是单个语句而不是复合语句,则就好像它被重写为包含原始子语句的复合语句一样。 [实施例:
if (x) int i;
可以等效地重写为
if (x) { int i; }
[...]
6.4.1
if
语句1如果条件(6.4)产生
true
,则执行第一个子语句。如果选择语句的else
部分存在且条件产生false
,则执行第二个子语句。 [...]
从6.4 1开始,您的示例代码相当于:
if (cond1) {
doSomething1();
} else {
if (cond2) {
doSomething2();
} else {
if (cond3) {
doSomething3();
} else {
doElse();
}
}
}
请注意,这并不意味着代码转换为上述代码,而是两者必须表现相同。
从6.4.1开始,当外部if
的条件为if
时,将执行内部false
语句。如果条件为true
,则执行第一个分支。虽然标准没有明确说明条件为true
时没有执行第二个分支,但是遗漏强烈暗示了这一点。
根据§1.91:
本国际标准中的语义描述定义了参数化的非确定性抽象机器。本国际标准对符合实施的结构没有要求。特别是,它们不需要复制或模拟抽象机器的结构。相反,需要符合实现来模拟(仅)抽象机器的可观察行为,如下所述。 5)
5)此条款有时被称为“as-if”规则,因为只要结果就像<一样,实施可以自由地忽略本国际标准的任何要求/ em>只要可以从程序的可观察行为中确定,就已遵守该要求。例如,实际实现不需要评估表达式的一部分,如果它可以推断出它的值没有被使用,并且没有产生影响程序的可观察行为的副作用。
因此,else
子语句的一部分可以在没有副作用的情况下执行,即使条件为true
,结果也会被丢弃。例如,如果pipeline错误地预测条件将是false
,则可以在处理器branch prediction内部分地执行子语句条件。但是,这种情况的影响必须是不明显的,因此(从您的角度来看),就好像这些子语句的行为符合§6.41和6.4.1 1所述。
答案 2 :(得分:5)
没有。唯一可以保证的是可观察的行为 “似乎”ifs按顺序进行评估。评价 条件甚至可以交错,cond2的一部分在cond1之前, 并且评估了cond1之后的另一部分。另一方面, 保证结果将“好像”ifs已被评估 顺序,如果某些条件有副作用,那些副作用 如果其中一个早期的ifs是真的,就不会发生。
关于优化,无论如何最有可能 条件优先。在实践中,编译器只会移动代码 知道运动会改善事物,所以如果条件是这样的话 或多或少独立,编译器无法“优化”它们 折叠它们的部分,然后订单将被保留。除非 编译器非常好,可以确定您的订购 不是最优的(基于分析器输出)。
答案 3 :(得分:0)
是的,条件是按if,else if,else结构的顺序检查的。 在给定的条件检查中,可以用括号稍微调整一些东西。
答案 4 :(得分:0)
重新排序if / else塔的语句不会表现为“as-if”它没有被重新排序(除非编译器当然可以证明它会是,就像某些检查总是真或假并且没有副作用)。
您绝对可以依赖if / else塔的订购。