如果我有例如以下功能:
void foo(DoThisSometimes, DoThisAlways)
{
if (DoThisSometimes == 1)
{
//Do stuff
}
//Do other stuff
{
一段内联代码将此函数调用DoThisSometimes
为 0,是否有任何编译器会从内联函数中删除这部分代码:
if (DoThisSometimes == 1)
{
//Do stuff
}
如果我有例如以下功能:
void foo(DoThisSometimes, DoThisAlways)
{
if (DoThisSometimes == 1)
{
//Do stuff
}
//Do other stuff
{
一段内联代码将此函数调用DoThisSometimes
为 0,是否有任何编译器会从内联函数中删除这部分代码:
if (DoThisSometimes == 1)
{
//Do stuff
}
一个体面的编译器当然应该进行这种优化,而 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 <puts@plt>
40041e: bf ea 05 40 00 mov $0x4005ea,%edi
400423: e8 c8 ff ff ff callq 4003f0 <puts@plt>
400428: bf ea 05 40 00 mov $0x4005ea,%edi
40042d: e8 be ff ff ff callq 4003f0 <puts@plt>
400432: 31 c0 xor %eax,%eax
400434: 48 83 c4 08 add $0x8,%rsp
400438: c3 retq
400439: 0f 1f 00 nopl (%rax)
无条件地叫puts
了三遍。
是的,很有可能。如果编译器可以找出值是什么,它通常会删除全部或部分 if 语句。
部分,我的意思是如果你这样做:
if (DoThisSometimes == 1 || foo == 0)
编译器也许可以删除DoThisSometimes==1
,但不能删除foo == 0
部分,因为foo
在内联点可能没有已知值。
请记住,这是编译器实现细节,因此编译器不保证删除该语句,如果它无法弄清楚值是什么,它肯定不会。它也可能在有 if 语句时决定不内联函数,因为它认为函数太长,然后当 if 语句消失时,内联就可以了。因此,虽然您可以预期会发生这种情况,但您当然不应该依赖它,如果它是超级关键的 - 在这种情况下,创建两个函数,一个用于“DoThisSometimes == 1”,一个用于“DoThisSometimes != 1”。