Function 空体功能通过叮当声得到优化吗?

Function 空体功能通过叮当声得到优化吗?,function,optimization,clang,compiler-optimization,Function,Optimization,Clang,Compiler Optimization,大概是这样的: static void MyFunction(int x, int y) {}; 当被调用时,叮当声会优化它们吗?当然,只要编译器在调用站点上可以看到定义。因为您已经声明它是静态的,所以它可能总是正确的 当然有-O3(实际上任何!=0)这取决于优化级别。如果没有优化,那么。但是,即使使用-O。如果您的函数未标记为static,则会有点复杂,因为该函数需要存在于其他翻译单元中,因此您可以,并且对它的调用在同一TU中省略,但函数本身必须仍然存在。给定代码: /* Optmizing

大概是这样的:

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

当被调用时,叮当声会优化它们吗?

当然,只要编译器在调用站点上可以看到定义。因为您已经声明它是静态的,所以它可能总是正确的

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

这取决于优化级别。如果没有优化,那么。但是,即使使用
-O
。如果您的函数未标记为
static
,则会有点复杂,因为该函数需要存在于其他翻译单元中,因此您可以,并且对它的调用在同一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-优化级别0和-g(调试)
  • 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    $0x10,%rsp
       0x0000000000000668 <+8>:     movl   $0x1,-0x4(%rbp)
       0x000000000000066f <+15>:    movl   $0x2,-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    $0x0,%eax
       0x000000000000068a <+42>:    leaveq
       0x000000000000068b <+43>:    retq
    End of assembler dump.
    
    主函数的汇编程序代码转储: 0x0000000000000660:推送%rbp 0x0000000000000661:mov%rsp,%rbp 0x0000000000000664:子$0x10,%rsp 0x0000000000000668:movl$0x1,-0x4(%rbp) 0x000000000000066f:movl$0x2,-0x8(%rbp) 0x0000000000000676:mov-0x8(%rbp),%edx 0x0000000000000679:mov-0x4(%rbp),%eax 0x000000000000067c:mov%edx,%esi 0x000000000000067e:mov%eax,%edi 0x0000000000000680:callq 0x68c 0x0000000000000685:mov$0x0,%eax 0x000000000000068a:LEVEQ 0x000000000000068b:retq 汇编程序转储结束。
GCC-优化级别1
  • gcc emptyfunc.c-O1-o emptyfunc-gccO1.x

    Dump of assembler code for function main:
       0x0000000000000660 <+0>:     mov    $0x0,%eax
       0x0000000000000665 <+5>:     retq
    End of assembler dump.
    
    主函数的汇编程序代码转储: 0x0000000000000660:mov$0x0,%eax 0x0000000000000665:retq 汇编程序转储结束。
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.
    
    主函数的汇编程序代码转储: 0x0000000000000530:xor%eax,%eax 0x0000000000000532:retq 汇编程序转储结束。
叮当声-优化级别0与-g(调试)
  • clangemptyfunc.c-o emptyfunc-clanggo.x-g-O0

    Dump of assembler code for function main:
       0x00000000004004c0 <+0>:     push   %rbp
       0x00000000004004c1 <+1>:     mov    %rsp,%rbp
       0x00000000004004c4 <+4>:     sub    $0x10,%rsp
       0x00000000004004c8 <+8>:     movl   $0x0,-0x4(%rbp)
       0x00000000004004cf <+15>:    movl   $0x1,-0x8(%rbp)
       0x00000000004004d6 <+22>:    movl   $0x2,-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    $0x10,%rsp
       0x00000000004004ee <+46>:    pop    %rbp
       0x00000000004004ef <+47>:    retq
    End of assembler dump.
    
    主函数的汇编程序代码转储: 0x00000000004004c0:推送%rbp 0x0000000000404C1:mov%rsp,%rbp 0x0000000000404C4:子$0x10,%rsp 0x0000000000404C8:movl$0x0,-0x4(%rbp) 0x00000000004004cf:movl$0x1,-0x8(%rbp) 0x0000000000404D6:movl$0x2,-0xc(%rbp) 0x0000000000404DD:mov-0x8(%rbp),%edi 0x00000000004004e0:mov-0xc(%rbp),%esi 0x0000000000404E3:callq 0x4004f0 0x00000000004004e8:xor%eax,%eax 0x0000000000404EA:添加$0x10,%rsp 0x00000000004004ee:弹出%rbp 0x0000000000404EF:retq 汇编程序转储结束。
Clang-优化级别1、2、3、Os(大小)、Ofast、Oz(大小II)
  • clangemptyfunc.c-o emptyfunc-clanggo1.x-O1
  • clangemptyfunc.c-o emptyfunc-clanggo2.x-O2
  • clangemptyfunc.c-o emptyfunc-clanggo3.x-O3
  • clangemptyfunc.c-o emptyfunc clangOs.x-Os
  • c-o emptyfunc clangOfast.x-Ofast
  • 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.
    
    主函数的汇编程序代码转储: 0x0000000000404C0:xor%eax,%eax 0x0000000000404C2:retq 汇编程序转储结束。

如您所见,是的,它当然会删除空函数。

为什么不编写一个简单的示例并自己检查一下呢?这是最好的学习方法值得一提的是,如果链接器没有在其他TU中实际使用,那么它应该被链接器删除。代码块作为项目符号列表的一部分时,需要缩进8个空格。(这比正常的4格缩进多了4格。)谢谢。这真的不是我的错。我没有使用任何缩进,因为我使用了
`
来标记块。无论在哪里,它都应该起作用。但无论如何,因为它似乎是一个bug,我已经删除了3个粗符号,并在所有行中添加了缩进。一件痛苦的事,而不是仅仅打开
`
粘贴代码,然后用
`
``结束,这不是一件事。它不用于标记块。使用反勾号的唯一地方是获取内联代码格式;这在文本字符串的开头使用一个反勾号,在末尾使用另一个反勾号。对于块代码格式,始终需要缩进。每行前面通常有4个空格,但有序/无序列表中的空格除外,其中所需的空格数加倍为8。(制表符也可以工作,其中1个制表符等于4个空格,但每个人都知道空格比制表符好。:-)