当函数体没有 return 语句时内联

inlining when function body has no return statement

我读到当函数体中不存在 "return" 语句时编译器可能不会执行内联,并且在 return 类型不是 void 的情况下也是如此。如果内联不能发生在 return 除了 void 以外的任何东西的函数中,为什么它需要一个 "return" 语句来使函数内联。假设简单代码如下:

此处声明为内联的函数在其主体中没有 "return" 语句。内联发生在这里吗?有什么方法可以知道编译器是否接受并执行了内联请求?

#include<stdio.h>
inline void call()
{
    printf("*****In call*****\n");
}

main()
{
    call();
}

这显然是一个特定于编译器的问题,但由于您使用的是 gcc,因此 gcc 生成的内容如下:

.cfi_startproc
subq    , %rsp
.cfi_def_cfa_offset 16
movl    $.LC0, %edi
call    puts
xorl    %eax, %eax
addq    , %rsp
.cfi_def_cfa_offset 8
ret
.cfi_endproc

其中 .LC0 是您的硬编码字符串 (complete assembly dump)。如您所见,这里没有调用 call,所以是的,gcc 确实使用 -O2.

内联此调用

I read that compiler may not perform inlining when "return" statement does not exist in function body

这根本不是真的。编译器当然可以内联 void 函数,但它是否内联 any 函数取决于它,即使你指定 inline 关键字。

请看这里:https://goo.gl/xEg6AK

这是生成的程序集:

.LC0:
    .string "*****In call*****"
main:
    subq    , %rsp
    movl    $.LC0, %edi
    call    puts
    movl    [=10=], %eax
    addq    , %rsp
    ret

GCC 在使用 -O 编译时会内联您的代码。它还用简单的 puts.

替换了 printf 调用

GCC 编译器为标准 C 语言提供了许多扩展,允许您向函数(以及此处不相关的类型和变量)添加 'attributes'。其中之一是 __attribute__((always_inline)),它覆盖了编译器的内联算法。

#include<stdio.h>
inline void __attribute__((always_inline)) call()
{
    printf("*****In call*****\n");
}

main()
{
    call();
}

在这种情况下,调用 printf 库例程的指令将在调用代码中出现 call 函数的位置内联。