2013-02-19 29 views
3

如果我有例如下面的函数:任何C++编译器在内联时是否删除总是保持相同答案的语句?

void foo(DoThisSometimes, DoThisAlways) 
{ 
    if (DoThisSometimes == 1) 
    { 
     //Do stuff 
    } 
    //Do other stuff 
{ 

而内联片的代码调用与DoThisSometimes此函数为0,在那里,将来自内联函数去掉这部分代码任何编译器:

if (DoThisSometimes == 1) 
    { 
     //Do stuff 
    } 
+8

也许大多数编译器都这么做。 – 2013-02-19 18:54:41

+1

如果编译器在用'DoThisSometimes'的文字值调用编译器时将内联函数'foo',它将(可能)移除该分支(并且对于'if ='中的代码'!= 1')。 – 2013-02-19 18:55:26

+0

大多数编译器可能会在启用优化的情况下执行此操作,特别是在应用“全局优化”时。 – 2013-02-19 18:55:29

回答

6

一个体面的编译器当然应该做这样的优化,而GCC呢。以下来源:

#include <cstdio> 

inline void foo(bool maybe) 
{ 
    if (maybe) { 
     printf("Maybe\n"); 
    } 
    printf("Always\n"); 
} 

int main() 
{ 
    foo(true); 
    foo(false); 
} 

编译(最优化-O3)到:

0000000000400410 <main>: 
    400410: 48 83 ec 08    sub $0x8,%rsp 
    400414: bf e4 05 40 00   mov $0x4005e4,%edi 
    400419: e8 d2 ff ff ff   callq 4003f0 <[email protected]> 
    40041e: bf ea 05 40 00   mov $0x4005ea,%edi 
    400423: e8 c8 ff ff ff   callq 4003f0 <[email protected]> 
    400428: bf ea 05 40 00   mov $0x4005ea,%edi 
    40042d: e8 be ff ff ff   callq 4003f0 <[email protected]> 
    400432: 31 c0     xor %eax,%eax 
    400434: 48 83 c4 08    add $0x8,%rsp 
    400438: c3      retq 
    400439: 0f 1f 00    nopl (%rax) 

调用puts三次,无条件地。

1

是的,很有可能。如果编译器能够确定这个值是什么,它通常会删除全部或部分if语句。

通过的部分,我的意思是,如果你这样做:

if (DoThisSometimes == 1 || foo == 0) 

编译器可以或许去除DoThisSometimes==1,但不是foo == 0部分,foo可能没有在内联点的已知值。

请记住,这是编译器实现细节,因此编译器不保证删除语句,并且如果它无法弄清楚该值是什么,那么肯定不会。它也可能决定在if语句中不内联函数,因为它认为函数太长,然后当if语句消失时,内联就可以了。所以,虽然你可以预料到会发生这种情况,但如果它是超级关键的话,你肯定不应该依赖它 - 在这种情况下,制作两个函数,一个用于“DoThisSometimes == 1”,另一个用于“DoThisSometimes!= 1”。

相关问题