c程序中,可以用宏代码提高执行效率。宏代码本身不是函数,但使用起来像函数,编译预处理器会拷贝宏代码的执行方式取代函数调用,省去了参数压栈、生成汇编语言的CALL调用、参数返回、执行return 等过程,从而提高了速度。使用宏代码的最大缺点是容易出错,预处理器在拷贝宏代码时常常产生意想不到的边际效应,例如:
#define MAX(a,b) (a)>(b)?(a):(b)
result = MAX(i,j)+2;
将被扩展为:
result = (i)>(j)?(i):(j)+2;
由于“+”运算符优先级高于“?”和“:”
宏代码应改为:#define MAX(a,b) ((a)>(b)?(a):(b))
宏代码的缺点如下:
1)使用宏代码的最大缺点是容易出错,预处理器在拷贝宏代码时常常产生意想不到的边际效应
2)不可调试,但是内联函数是可以调试的。内联函数的“可调试”不是说他展开后还能调试,而是在程序的调试“Debug”版本里根本就没有真正的内联,编译器像处理普通函数那样为它生成含有调试信息的可执行代码。在程序的Release·版本里编译器才会真正的内联。
3)对于c++而言,使用宏代码还有另一个缺点就是:无法操作类的私有数据成员。
让我们看看c++中内联函数是如何工作的:
内联函数的优点:
所以无论是《Effective C++》中的 “Prefer consts,enums,and inlines to #defines” 条款,还是《高质量程序设计指南——C++/C语言》中的“用函数内联取代宏”,宏在C++中基本是被废了。
慎用内联函数:
内联虽有它的好处,但是也要慎用,以下摘自《高质量程序设计指南——C++/C语言》:
而在Google C++编码规范中则规定得更加明确和详细:
Tip: 只有当函数只有 10 行甚至更少时才将其定义为内联函数.
定义: 当函数被声明为内联函数之后, 编译器会将其内联展开, 而不是按通常的函数调用机制进行调用.
优点: 当函数体比较小的时候, 内联该函数可以令目标代码更加高效. 对于存取函数以及其它函数体比较短, 性能关键的函数, 鼓励使用内联.
缺点: 滥用内联将导致程序变慢. 内联可能使目标代码量或增或减, 这取决于内联函数的大小. 内联非常短小的存取函数通常会减少代码大小, 但内联一个相当大的函数将戏剧性的增加代码大小. 现代处理器由于更好的利用了指令缓存, 小巧的代码往往执行更快。
结论: 一个较为合理的经验准则是, 不要内联超过 10 行的函数. 谨慎对待析构函数, 析构函数往往比其表面看起来要更长, 因为有隐含的成员和基类析构函数被调用!
另一个实用的经验准则: 内联那些包含循环或 switch 语句的函数常常是得不偿失 (除非在大多数情况下, 这些循环或 switch 语句从不被执行).
参考自:《Effective C++》
《高质量程序设计指南——C++/C语言》
http://www.jb51.net/article/46261.htm