我是靠谱客的博主 苗条夕阳,最近开发中收集的这篇文章主要介绍inline内联类型函数(inline、__always_inline、noinline)1. 定义2. 接口3. 优缺点4. inline、__always_inline、noinline的区别5. 与宏的区别6. 验证inline的方法,觉得挺不错的,现在分享给大家,希望可以做个参考。
概述
目录
- 1. 定义
- 2. 接口
- 3. 优缺点
- 4. inline、__always_inline、noinline的区别
- 5. 与宏的区别
- 6. 验证inline的方法
- C程序
- 编译为汇编
1. 定义
TODO
2. 接口
#define __inline__ inline
#define __inline inline
#define __always_inline inline __attribute__((always_inline))
#define noinline __attribute__((noinline))
3. 优缺点
对于inline:
优点:省去调用子函数所消耗的时间,代码
执行效率更高
。
缺点:代码的体积增大
。
适用场景:
代码量小
,调用位置少
,调用频率高
。
不适用场景:与适用场景相反,重点是递归函数
。
4. inline、__always_inline、noinline的区别
inline
仅仅是建议编译器内联,但不一定内联。
__always_inline
强制内联。
noinline
强制不内联。
5. 与宏的区别
- inline
预处理
阶段不会内联
- inline类型的函数可以进行
参数有效性的检测
- inline类型的函数
返回值
可以强制转换
为合适的类型
6. 验证inline的方法
C程序
// inline_test.c
#include <stdio.h>
/* 普通函数*/
static void function_1(void)
{
printf("static void function_1()n");
return;
}
/* inline: 建议内联 */
static inline void function_2(void)
{
printf("static inline void function_2()n");
return;
}
/* __always_inline: 强制内联 */
static __always_inline void function_3(void)
{
printf("static __always_inline void function_3()n");
return;
}
/* noinline: 不允许内联 */
static __attribute__((noinline)) void function_4(void)
{
printf("static __always_inline void function_4()n");
return;
}
int main(int argc, const char *argv[])
{
printf("functiontion main()n");
function_1();
function_2();
function_3();
function_4();
return 0;
}
编译为汇编
命令:
gcc -S inline_test.c -o inline_test.s
从汇编代码可以看出:
function_3被强制内联;
function_1、function_2、function_4都未被内联。
// inline_test.s
.file "inline_test.c"
.section .rodata
.LC0:
.string "static void function_1()"
.text
.type function_1, @function
function_1:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
movq %rsp, %rbp
.cfi_offset 6, -16
.cfi_def_cfa_register 6
movl $.LC0, %edi
call puts
leave
ret
.cfi_endproc
.LFE0:
.size function_1, .-function_1
.section .rodata
.align 8
.LC1:
.string "static inline void function_2()"
.text
.type function_2, @function
function_2:
.LFB1:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
movq %rsp, %rbp
.cfi_offset 6, -16
.cfi_def_cfa_register 6
movl $.LC1, %edi
call puts
leave
ret
.cfi_endproc
.LFE1:
.size function_2, .-function_2
.section .rodata
.align 8
.LC2:
.string "static __always_inline void function_4()"
.text
.type function_4, @function
function_4:
.LFB3:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
movq %rsp, %rbp
.cfi_offset 6, -16
.cfi_def_cfa_register 6
movl $.LC2, %edi
call puts
leave
ret
.cfi_endproc
.LFE3:
.size function_4, .-function_4
.section .rodata
.LC3:
.string "functiontion main()"
.align 8
.LC4: // static __always_inline, 强制内联
.string "static __always_inline void function_3()"
.text
.globl main
.type main, @function
main:
.LFB4:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
movq %rsp, %rbp
.cfi_offset 6, -16
.cfi_def_cfa_register 6
subq $16, %rsp
movl %edi, -4(%rbp)
movq %rsi, -16(%rbp)
movl $.LC3, %edi
call puts
call function_1 // static, 调用的形式
call function_2 // static inline, 建议内联,但不一定会内联
movl $.LC4, %edi // function_3()被强制内联于此
call puts
call function_4 // function_4()强制不内联
movl $0, %eax
leave
ret
.cfi_endproc
.LFE4:
.size main, .-main
.ident "GCC: (Ubuntu/Linaro 4.4.7-8ubuntu1) 4.4.7"
.section .note.GNU-stack,"",@progbits
最后
以上就是苗条夕阳为你收集整理的inline内联类型函数(inline、__always_inline、noinline)1. 定义2. 接口3. 优缺点4. inline、__always_inline、noinline的区别5. 与宏的区别6. 验证inline的方法的全部内容,希望文章能够帮你解决inline内联类型函数(inline、__always_inline、noinline)1. 定义2. 接口3. 优缺点4. inline、__always_inline、noinline的区别5. 与宏的区别6. 验证inline的方法所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复