我读到当函数体中不存在“return”语句时以及返回类型不是void的情况下,编译器可能不会执行内联。如果对于返回除void之外的任何函数的函数不会发生内联,为什么它需要一个“return”语句来使函数内联。假设简单的代码如下:
此处声明为内联的函数在其正文中没有“return”语句。内联是否发生在这里?有没有什么办法可以让我们知道内联请求是否被编译器接受并执行了?
#include<stdio.h>
inline void call()
{
printf("*****In call*****\n");
}
main()
{
call();
}
答案 0 :(得分:2)
这显然是一个编译器特定的问题,但由于你使用gcc,这是gcc产生的:
.cfi_startproc
subq $8, %rsp
.cfi_def_cfa_offset 16
movl $.LC0, %edi
call puts
xorl %eax, %eax
addq $8, %rsp
.cfi_def_cfa_offset 8
ret
.cfi_endproc
其中.LC0
是您的硬编码字符串(complete assembly dump)。正如您所看到的,此处没有call
的来电,所以是的,gcc会使用-O2
内联此来电。
答案 1 :(得分:1)
我读到编译器可能无法在&#34;返回&#34;声明 在函数体中不存在
这根本不是真的。编译器当然可以内联void函数,但是即使你指定inline
关键字,它是否内联任何函数也是如此。
这是生成的程序集:
.LC0:
.string "*****In call*****"
main:
subq $8, %rsp
movl $.LC0, %edi
call puts
movl $0, %eax
addq $8, %rsp
ret
GCC在使用-O
编译时会内联您的代码。它还用简单的puts
替换了printf调用。
答案 2 :(得分:1)
GCC编译器为标准C语言提供了许多扩展,允许您向函数添加“属性”(以及此处不相关的类型和变量)。其中一个是__attribute__((always_inline))
,它会覆盖编译器的内联算法。
#include<stdio.h>
inline void __attribute__((always_inline)) call()
{
printf("*****In call*****\n");
}
main()
{
call();
}
在这种情况下,调用printf
库例程的指令将在call
函数出现在调用代码中的位置内联。