clang 是否优化了空体功能?

Do empty body functions get optimized by clang?

像这样:

static void MyFunction(int x, int y) {};

Clang 会在调用时优化它们吗?

当然可以,只要定义对调用站点的编译器可见即可。既然你已经宣布它 static 那可能永远都是真的。

当然有 -O3(实际上任何 != 0)

这取决于优化级别。如果您没有优化,那么 you'll probably still end up with a function. However, even with -O you'll see it disappear. If your function were not marked static it would be a bit more complicated because the function would need to exist for other translation units, so you might see an empty body,并且在同一个 TU 中省略了对它的调用,但函数本身必须仍然存在。

给定代码:

/* Optmizing empty functions */

  static void myFunc(int x, int y); 

  int main(void)
  {
      int x=1, y=2;

      myFunc(x, y); 

      return 0;
  }

static void myFunc(int x, int y)
{
      ;   
}

每个优化级别生成的程序集如下所示:

GCC - 带 -g 的优化级别 0(调试)

  • gcc emptyfunc.c -g -O0 -o emptyfunc.x

    Dump of assembler code for function main:
       0x0000000000000660 <+0>:     push   %rbp
       0x0000000000000661 <+1>:     mov    %rsp,%rbp
       0x0000000000000664 <+4>:     sub    [=11=]x10,%rsp
       0x0000000000000668 <+8>:     movl   [=11=]x1,-0x4(%rbp)
       0x000000000000066f <+15>:    movl   [=11=]x2,-0x8(%rbp)
       0x0000000000000676 <+22>:    mov    -0x8(%rbp),%edx
       0x0000000000000679 <+25>:    mov    -0x4(%rbp),%eax
       0x000000000000067c <+28>:    mov    %edx,%esi
       0x000000000000067e <+30>:    mov    %eax,%edi
       0x0000000000000680 <+32>:    callq  0x68c <myFunc>
       0x0000000000000685 <+37>:    mov    [=11=]x0,%eax
       0x000000000000068a <+42>:    leaveq
       0x000000000000068b <+43>:    retq
    End of assembler dump.
    

GCC - 优化级别 1

  • gcc emptyfunc.c -O1 -o emptyfunc-gccO1.x

    Dump of assembler code for function main:
       0x0000000000000660 <+0>:     mov    [=12=]x0,%eax
       0x0000000000000665 <+5>:     retq
    End of assembler dump.
    

GCC - 优化级别 2、3、Os(大小)、Og(调试)和 Ofast

  • gcc emptyfunc.c -O2 -o emptyfunc-gccO2.x
  • gcc emptyfunc.c -O3 -o emptyfunc-gccO3.x
  • gcc emptyfunc.c -Os -o emptyfunc-gccOs.x
  • gcc emptyfunc.c -Og -o emptyfunc-gccOg.x
  • gcc emptyfunc.c -Ofast -o emptyfunc-gccOfast.x

    Dump of assembler code for function main:
       0x0000000000000530 <+0>:     xor    %eax,%eax
       0x0000000000000532 <+2>:     retq
    End of assembler dump.
    

Clang - 带 -g 的优化级别 0(调试)

  • clang emptyfunc.c -o emptyfunc-clangO0.x -g -O0

    Dump of assembler code for function main:
       0x00000000004004c0 <+0>:     push   %rbp
       0x00000000004004c1 <+1>:     mov    %rsp,%rbp
       0x00000000004004c4 <+4>:     sub    [=14=]x10,%rsp
       0x00000000004004c8 <+8>:     movl   [=14=]x0,-0x4(%rbp)
       0x00000000004004cf <+15>:    movl   [=14=]x1,-0x8(%rbp)
       0x00000000004004d6 <+22>:    movl   [=14=]x2,-0xc(%rbp)
       0x00000000004004dd <+29>:    mov    -0x8(%rbp),%edi
       0x00000000004004e0 <+32>:    mov    -0xc(%rbp),%esi
       0x00000000004004e3 <+35>:    callq  0x4004f0 <myFunc>
       0x00000000004004e8 <+40>:    xor    %eax,%eax
       0x00000000004004ea <+42>:    add    [=14=]x10,%rsp
       0x00000000004004ee <+46>:    pop    %rbp
       0x00000000004004ef <+47>:    retq
    End of assembler dump.
    

Clang - 优化级别 1、2、3,Os(大小),Ofast,Oz(大小 II)

  • clang emptyfunc.c -o emptyfunc-clangO1.x -O1
  • clang emptyfunc.c -o emptyfunc-clangO2.x -O2
  • clang emptyfunc.c -o emptyfunc-clangO3.x -O3
  • clang emptyfunc.c -o emptyfunc-clangOs.x -Os
  • clang emptyfunc.c -o emptyfunc-clangOfast.x -Ofast
  • clang emptyfunc.c -o emptyfunc-clangOz.x -Oz

    Dump of assembler code for function main:
       0x00000000004004c0 <+0>:     xor    %eax,%eax
       0x00000000004004c2 <+2>:     retq
    End of assembler dump.
    

如你所见,是的,当然会去掉空函数