首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >内联与静态内联c

内联与静态内联c
EN

Stack Overflow用户
提问于 2018-07-18 13:58:03
回答 2查看 290关注 0票数 2

下面是在x86_64上运行的一些简单测试,以显示在使用内联语句时生成的汇编程序代码:

试验1

代码语言:javascript
复制
static inline void
show_text(void)
{
  printf("Hello\n");
}

int main(int argc, char *argv[])
{
  show_text();
  return 0;
}

和汇编程序:

代码语言:javascript
复制
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优化标志

代码语言:javascript
复制
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

代码语言:javascript
复制
#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;
}

生产:

代码语言:javascript
复制
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

EN

回答 2

Stack Overflow用户

发布于 2018-07-18 14:07:08

这是C语言标准人士的一个值得怀疑的决定.使用inline并不能保证函数被内联.关键字仅向编译器暗示函数可以内联。

我与ISO就这个主题进行了长时间的交流;这遵循了MISRA准则,其中要求使用static关键字在模块范围内声明所有的static函数。他们的逻辑是,在某些情况下,编译器不需要内联函数.同样,在某些情况下,非内联函数需要具有全局范围!

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

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

票数 0
EN

Stack Overflow用户

发布于 2018-07-18 14:07:40

在第一个测试中,您将禁用优化。衬里是一种优化方法。不要指望它会发生。

另外,inline关键字现在不再像过去那样工作了。我想说的是,它的唯一目的是在头中有函数,而不存在关于重复符号的链接器错误(当多个cpp文件使用这样的头时)。

让编译器完成它的工作。只需启用优化(包括LTO),不要担心细节。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51403967

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档