任何C++编译器都要删除在内联时总是包含相同答案的if语句

Do any C++ compilers remove if statements that always hold the same answer when inlining?

本文关键字:包含相 答案 语句 if 编译器 C++ 删除 任何      更新时间:2023-10-16

例如,如果我有以下函数:

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("Mayben");
    }
    printf("Alwaysn");
}
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语句消失时,可以内联。因此,虽然你可以预期会发生这种情况,但如果它非常关键,你当然不应该依赖它——在这种情况下,制作两个函数,一个用于"DoThisSome==1",另一个用于"DoThisSome!=1"。