gpt4 book ai didi

c - 内联与静态内联 c

转载 作者:太空宇宙 更新时间:2023-11-04 04:16:39 26 4
gpt4 key购买 nike

以下是在 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 函数

测试 3show_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 在汇编程序中定义,未考虑内联建议

我了解 inline 关键字不会强制内联。但是对于Test 1的结果,有什么可以阻止main中的show_text代码替换呢?

到目前为止,我习惯于在我的 C 源代码中内联一些小的静态函数。但从这些结果来看,它似乎毫无用处。为什么我应该在使用一些现代编译器(并且可能编译优化代码)时声明我的一些小函数 static inline

最佳答案

这是 C 语言标准人员的那些有问题的决定之一......使用 inline 并不能保证函数被内联......关键字仅向编译器建议函数可以内联。

我已与 ISO WG 就此主题进行了长时间的交流;这遵循了 MISRA 指南,该指南要求使用 static 关键字在模块范围内声明所有 inline 函数。他们的逻辑是,可能存在编译器不需要内联函数的情况……同样,可能存在非内联函数需要具有全局作用域的情况!

恕我直言,如果程序员添加了 inline 关键字,那么建议他们知道自己在做什么,并且该函数应该是内联的。

正如您所建议的,在当前形式下,inline 关键字实际上毫无意义,除非编译器认真对待它。

关于c - 内联与静态内联 c,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51403967/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com