下面是在x86_64上运行的一些简单测试,以显示在使用内联语句时生成的汇编程序代码:
试验1
static inline void
show_text(void)
{
printf("Hello\n");
}
int main(int argc, char *argv[])
{
show_text();
return 0;
}和汇编程序:
gcc -O0 -fno-asynchronous-unwind-tables -S -masm=att main.c && less main.s
.file "main.c"
.text
.section .rodata
.LC0:
.string "Hello"
.text
.type show_text, @function
show_text:
pushq %rbp
movq %rsp, %rbp
leaq .LC0(%rip), %rdi
call puts@PLT
nop
popq %rbp
ret
.size show_text, .-show_text
.globl main
.type main, @function
main:
pushq %rbp
movq %rsp, %rbp
subq $16, %rsp
movl %edi, -4(%rbp)
movq %rsi, -16(%rbp)
call show_text
movl $0, %eax
leave
ret
.size main, .-main
.ident "GCC: (GNU) 7.3.1 20180312"
.section .note.GNU-stack,"",@progbits测试1结果:编译器没有考虑到内联建议
测试2
与测试1相同的代码,但带有-O1优化标志
gcc -O1 -fno-asynchronous-unwind-tables -S -masm=att main.c && less main.s
.file "main.c"
.text
.section .rodata.str1.1,"aMS",@progbits,1
.LC0:
.string "Hello"
.text
.globl main
.type main, @function
main:
subq $8, %rsp
leaq .LC0(%rip), %rdi
call puts@PLT
movl $0, %eax
addq $8, %rsp
ret
.size main, .-main
.ident "GCC: (GNU) 7.3.1 20180312"
.section .note.GNU-stack,"",@progbits测试2结果:不再是在汇编程序中定义的show_text函数
测试3 show_text未声明为内联,-O1优化标志
测试3结果:不再定义在汇编程序中的show_text函数,有或没有内联:相同生成的代码
测试4
#include <stdio.h>
static inline void
show_text(void)
{
printf("Hello\n");
printf("Hello\n");
printf("Hello\n");
printf("Hello\n");
printf("Hello\n");
printf("Hello\n");
}
int main(int argc, char *argv[])
{
show_text();
show_text();
return 0;
}生产:
gcc -O1 -fno-asynchronous-unwind-tables -S -masm=att main.c && less main.s
.file "main.c"
.text
.section .rodata
.LC0:
.string "Hello"
.text
.type show_text, @function
show_text:
pushq %rbp
movq %rsp, %rbp
leaq .LC0(%rip), %rdi
call puts@PLT
leaq .LC0(%rip), %rdi
call puts@PLT
leaq .LC0(%rip), %rdi
call puts@PLT
leaq .LC0(%rip), %rdi
call puts@PLT
leaq .LC0(%rip), %rdi
call puts@PLT
leaq .LC0(%rip), %rdi
call puts@PLT
nop
popq %rbp
ret
.size show_text, .-show_text
.globl main
.type main, @function
main:
pushq %rbp
movq %rsp, %rbp
subq $16, %rsp
movl %edi, -4(%rbp)
movq %rsi, -16(%rbp)
call show_text
call show_text
movl $0, %eax
leave
ret
.size main, .-main
.ident "GCC: (GNU) 7.3.1 20180312"
.section .note.GNU-stack,"",@progbits测试4结果:在汇编程序中定义的 show_text,没有考虑到内联建议
我理解内联关键字不会强制内联。但是对于测试1结果,什么可以阻止show_text代码的替换?
到目前为止,我经常在C源代码中内联一些小的静态函数。但从这些结果来看,这似乎是毫无用处的。为什么在使用一些现代编译器(并可能编译优化的代码)时,我应该声明一些小函数-- static inline?
发布于 2018-07-18 14:07:08
这是C语言标准人士的一个值得怀疑的决定.使用inline并不能保证函数被内联.关键字仅向编译器暗示函数可以内联。
我与ISO就这个主题进行了长时间的交流;这遵循了MISRA准则,其中要求使用static关键字在模块范围内声明所有的static函数。他们的逻辑是,在某些情况下,编译器不需要内联函数.同样,在某些情况下,非内联函数需要具有全局范围!
如果程序员添加了inline关键字,那么建议是他们知道自己在做什么,这个函数应该是内联的。
正如您所建议的,在当前的形式中,inline关键字实际上是没有意义的,除非编译器认真对待它。
发布于 2018-07-18 14:07:40
在第一个测试中,您将禁用优化。衬里是一种优化方法。不要指望它会发生。
另外,inline关键字现在不再像过去那样工作了。我想说的是,它的唯一目的是在头中有函数,而不存在关于重复符号的链接器错误(当多个cpp文件使用这样的头时)。
让编译器完成它的工作。只需启用优化(包括LTO),不要担心细节。
https://stackoverflow.com/questions/51403967
复制相似问题