当函数体没有 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
关键字。
这是生成的程序集:
.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
函数的位置内联。
我读到当函数体中不存在 "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
关键字。
这是生成的程序集:
.LC0:
.string "*****In call*****"
main:
subq , %rsp
movl $.LC0, %edi
call puts
movl [=10=], %eax
addq , %rsp
ret
GCC 在使用 -O
编译时会内联您的代码。它还用简单的 puts
.
GCC 编译器为标准 C 语言提供了许多扩展,允许您向函数(以及此处不相关的类型和变量)添加 'attributes'。其中之一是 __attribute__((always_inline))
,它覆盖了编译器的内联算法。
#include<stdio.h>
inline void __attribute__((always_inline)) call()
{
printf("*****In call*****\n");
}
main()
{
call();
}
在这种情况下,调用 printf
库例程的指令将在调用代码中出现 call
函数的位置内联。