在C++里边推荐用内联函数来代替宏,这里面当然有它这样做的理由。下面就来总结一下宏与内联各自的优缺点。
刚学C时,你写的第一个宏可能是这样的:
如果要调用这个宏函数,我们会这样:MAX(a, b); 我们都知道,编译器对宏只是做简的替换,所以编译预处理阶段结束后这条语句就会被替换为 a > b ? a : b ; ,这样,宏就完成了它的使命。这句代码是没有问题的,但是,当这样传参的时候:MAX(a, b) + c; ,这条语句会被替换为 a > b ? a : b + c; 问题就暴漏出来了。由于优先级而引发的边界问题。所以一半定义宏的时候,都会加上很多的括号,像下面这样:#define MAX(a, b) a>b ? a : b
#define MAX(a, b) ((a) > (b) ? (a) : (b);
所以,宏有一个缺点就是书写麻烦。另外,宏的参数是没有类型检测的,发生错误不容易定位错误源。
然后,宏在编译预处理阶段进行展开,不利于调试。
再比如,这样调用宏,MAX(a++, b); 展开后,变成了 a++ > b ? a++ : b ; 这个表达式中a变量是有可能被求值两次,所以可能得到错误的结果。
所以,当参数为带有副作用时,可能引发不易察觉的错误。
最后,当一个宏被多次调用时,展开后的代码可能会特别长。这也是一个缺点。
当然宏也有它的优点,那就是省去了调用函数的开销,提高了效率。
在C++中,我们有了一个关键字 inline ,用它修饰的函数,继承了宏的这种优点,摈除了宏一些的缺点。
inline的使用很简单,即在函数定义之前加关键字 inine即可(注意是定义前加)。
1. 内联函数书写简单;
2. 有类型检测
3. DEBUG版本不展开,方便调试,Realse版本展开,提高效率。
4. 而且不存在优先级不同和参数有副作用时引发的意外错误,因为它是个函数。
5. inline关键字对编译器来说只是个建议,具体是否作为内联函数,还要看编译器的决定(比如当函数中有循环或着递归时是不会作为内联函数的)。
inline 函数的定义对编译器而言必须是可见的,以便编译器能够在调用点内联展开该函数的代码。此时,仅有函数原型是不够的。所以一般把内联函数的定义放在头文件。
最后再说一点,在定义在类体内(花括号里边)的函数默认加了inline关键字。
宏与内联
最新推荐文章于 2022-08-01 17:10:04 发布