C++中内联函数何时被编译器禁止?
2015-10-06 17:49
1511 查看
C++当中定义内联函数,可以让编译器将对内联函数的调用直接展开。
这就多少有点像宏定义了,而且没有宏定义的缺点(预处理替换,无法当成变量链接到符号表、调用有可能导致参数异常被改、等等)。
使用内联函数可以避免函数调用的开销(栈开辟、返回地址设定、栈展开),在一定的程度上可以提高程序的性能。但是这种提高是有代价的。
编译器将函数展开,会直接导致可执行程序变大。(导致运行缺页、cache命中率降低 effective c++ page 135)
编译器在某些情况下会禁止inline:
1:编译器禁止虚函数inline
inline展开是在编译时进行的(宏定义是在预处理时展开的),而虚函数是在运行时决定调用哪个函数的。因此编译器对虚函数的inline无能为力
(g++下试验过,编译器连警告都没有一个)
2:带有循环或者递归的调用
如何inline函数过于复杂,复杂到函数本身执行的成本,比函数调用(栈开销)成本还要高,编译器禁止inline
3: 通过函数指针调用inline函数
虽然编译器会展开inline函数,但是还是会为内联函数生成函数本体。通过函数指针,使得其等于内联函数,通过函数指针调用,无法 inline
inline void f() {...}
void (*p)()=f;
p(); //此处无法内联
这就多少有点像宏定义了,而且没有宏定义的缺点(预处理替换,无法当成变量链接到符号表、调用有可能导致参数异常被改、等等)。
使用内联函数可以避免函数调用的开销(栈开辟、返回地址设定、栈展开),在一定的程度上可以提高程序的性能。但是这种提高是有代价的。
编译器将函数展开,会直接导致可执行程序变大。(导致运行缺页、cache命中率降低 effective c++ page 135)
编译器在某些情况下会禁止inline:
1:编译器禁止虚函数inline
inline展开是在编译时进行的(宏定义是在预处理时展开的),而虚函数是在运行时决定调用哪个函数的。因此编译器对虚函数的inline无能为力
(g++下试验过,编译器连警告都没有一个)
2:带有循环或者递归的调用
如何inline函数过于复杂,复杂到函数本身执行的成本,比函数调用(栈开销)成本还要高,编译器禁止inline
3: 通过函数指针调用inline函数
虽然编译器会展开inline函数,但是还是会为内联函数生成函数本体。通过函数指针,使得其等于内联函数,通过函数指针调用,无法 inline
inline void f() {...}
void (*p)()=f;
p(); //此处无法内联
相关文章推荐
- 黑马程序员——OC语言基础---@synthesize关键字介绍和使用
- C++中,get和getline函数的区别
- 位运算符
- 黑马程序员——OC语言基础---@property关键字介绍及使用
- C++深复制与浅复制(七)
- C/C++中指针所能指向的地址范围
- C/C++ 笔试、面试题目总结,
- 交换两个数的值,不借助第三方变量
- Implementing a simple smart pointer in C++
- c++primer plus第十七章-输入和输出概述
- 黑马程序员——OC语言基础---description方法介绍及重写
- 黑马程序员——OC语言基础---extern和static关键字
- C++初始化变量
- 黑马程序员——OC语言基础---Static关键字使用
- OC语言-NSMutableArray为什么要用strong来修饰
- 黑马程序员——OC语言基础---封装的概念及原理
- c语言'\0' 意思
- C++中的函数模板&&类模板
- C++输入输出流实现未知数目的输入(相当于实现python的split函数)
- C++中的try..catch