C++专题:内联函数 vs. 宏定义
一.区别
本质上,宏定义就是纯粹的文本替换,而内联函数是函数,其执行结果与普通函数调用是一致的。
- 编译阶段:宏定义是在预编译阶段展开的,内联函数是在编译阶段展开。
- 传参方式:内联函数是按值传递参数,跟普通函数别无二致,宏定义不能按值传递
- 二义性:宏定义容易出现二义性的问题,内联函数不存在这种问题
二.举例说明
(一)传参
- 宏定义
#include <iostream>
using namespace std;
#define SQUARE(X) ((X)*(X))
int main()
{
int a = 1;
cout<< SQUARE(a++) << endl;
cout<< a << endl;
return 0;
}
编译告警:
define.cpp:9:17: warning: multiple unsequenced modifications to 'a' [-Wunsequenced]
cout<< SQUARE(a++) << endl;
^~
define.cpp:4:21: note: expanded from macro 'SQUARE'
#define SQUARE(X) ((X)*(X))
^ ~
1 warning generated.
输出结果:
2
3
分析如下:SQUARE(a++) 被展开为((a++)*(a++)),执行了两次自增操作,最终结果是2,a的值变为3
- 内联函数
#include <iostream>
using namespace std;
inline int square(int x) { return x * x; }
int main()
{
int a = 1;
cout<< square(a++) << endl;
cout<< a << endl;
return 0;
}
输出结果:
1
2
分析如下:符合预期
(二)二义性
- 宏定义
#include <iostream>
using namespace std;
#define SQUARE(X) X*X
int main()
{
cout<< SQUARE(1 + 1) << endl;
return 0;
}
输出如下:
8
分析如下:从语义上理解是SQUARE(1+1)的值为4。实际上,SQUARE(1 + 1)展开为1+1*1+1,结果是3
- 内联函数
#include <iostream>
using namespace std;
inline int square(int x) { return x * x; }
int main()
{
cout<< square(1+1) << endl;
return 0;
}
输出结果:
4
分析如下:符合预期,内联函数有完整的函数语义,不会出现二义性
三.注意事项
- 对于体积小且频繁调用的函数,可以定义为内联函数。
- 内联函数一般定义在头文件,编译器需要在编译阶段找到其完整定义。
- 内联函数之所以能提高性能是在于,函数本身的执行时间小于函数调用的开销,我的理解是本质上是空间换时间。
- 内联函数的定义只是程序员的一种请求,编译器并不一定会满足要求。比如函数体存在递归调用或者体积过大,那么编译器会将其视为普通函数。
- 在C++中,在类内定义的成员函数默认是内联函数,内联函数不可以定义为虚函数(可以思考下为什么?)。

浙公网安备 33010602011771号