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
主函数的汇编程序代码转储: 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 汇编程序转储结束。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.
- gcc emptyfunc.c-O1-o emptyfunc-gccO1.x
主函数的汇编程序代码转储: 0x0000000000000660:mov$0x0,%eax 0x0000000000000665:retq 汇编程序转储结束。Dump of assembler code for function main: 0x0000000000000660 <+0>: mov $0x0,%eax 0x0000000000000665 <+5>: retq End of assembler dump.
- 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
主函数的汇编程序代码转储: 0x0000000000000530:xor%eax,%eax 0x0000000000000532:retq 汇编程序转储结束。Dump of assembler code for function main: 0x0000000000000530 <+0>: xor %eax,%eax 0x0000000000000532 <+2>: retq End of assembler dump.
- clangemptyfunc.c-o emptyfunc-clanggo.x-g-O0
主函数的汇编程序代码转储: 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 汇编程序转储结束。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.
- 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
主函数的汇编程序代码转储: 0x0000000000404C0:xor%eax,%eax 0x0000000000404C2:retq 汇编程序转储结束。Dump of assembler code for function main: 0x00000000004004c0 <+0>: xor %eax,%eax 0x00000000004004c2 <+2>: retq End of assembler dump.
如您所见,是的,它当然会删除空函数。为什么不编写一个简单的示例并自己检查一下呢?这是最好的学习方法值得一提的是,如果链接器没有在其他TU中实际使用,那么它应该被链接器删除。代码块作为项目符号列表的一部分时,需要缩进8个空格。(这比正常的4格缩进多了4格。)谢谢。这真的不是我的错。我没有使用任何缩进,因为我使用了
`
来标记块。无论在哪里,它都应该起作用。但无论如何,因为它似乎是一个bug,我已经删除了3个粗符号,并在所有行中添加了缩进。一件痛苦的事,而不是仅仅打开`
粘贴代码,然后用`
``结束,这不是一件事。它不用于标记块。使用反勾号的唯一地方是获取内联代码格式;这在文本字符串的开头使用一个反勾号,在末尾使用另一个反勾号。对于块代码格式,始终需要缩进。每行前面通常有4个空格,但有序/无序列表中的空格除外,其中所需的空格数加倍为8。(制表符也可以工作,其中1个制表符等于4个空格,但每个人都知道空格比制表符好。:-)