C++中的const常量可以替代宏常数定义,如:
C++中是否有解决方案替代宏代码片段呢?
C++编译器可以将一个函数内联编译
被C++编译器内联编译的函数叫做内联函数
C++编译器直接将函数体插入到函数调用的地方
内联函数没有普通函数调用时的额外开销(压栈、跳转、返回)
C++编译器不一定满足函数的内联请求
宏代码块示例:
1 #include <stdio.h> 2 3 #define FUNC(a, b) ((a) < (b) ? (a) : (b)) 4 5 inline int func(int a, int b) 6 { 7 return a < b ? a : b; 8 } 9 10 int main(int argc, char *argv[]) 11 { 12 int a = 1; 13 int b = 3; 14 int c = FUNC(++a, b); 15 16 printf("a = %d ", a); 17 printf("b = %d ", b); 18 printf("c = %d ", c); 19 20 return 0; 21 }
执行结果如下:
将宏定义注释掉,换成内联函数调用的形式,结果如下:
可见宏代码块带来的副作用,调用内联函数的输出才是正确的结果。
我们将调用内联函数的情形进行反汇编,在VS2010中结果如下:
反汇编中依然有func函数调用,这说明内联并没有成功。因此,再次说明了,inline关键字仅仅是请求编译器将函数做内联处理。如果我们对VS2010进行设置,强制内联,则可以成功内联。
在linux中的eclipse下进行反汇编,结果如下:
这说明g++编译器也拒绝了inline的请求。
内联函数与宏代码块的比较:
在C++开发中首选内联函数。
现在C++编译器的语法扩展使得我们可以强制内联:
在MSVC中,我们屏蔽掉inline关键字,而改用__forceinline则可以强制内联,(inline是标准C++支持的,但是只是请求内联,不是强制,__forceinline是MSVC扩展的语法)
eclipse中可以使用__attribute__((always_inline))强制内联,这个也是g++编译器的扩展,如下:
C++中inline内联编译的限制:
在现代编译器中,编译技术非常优秀,以上的限制也不是完全不能存在的,上述程序中就存在一个for循环。只要函数不太过于夸张,现代编译器都是可以内联的。
小结:
C++中可以通过inline声明内联函数
编译器直接将内联函数扩展到函数调用的地方
inline只是一种请求,编译器不一定允许这种请求
内联函数省去了函数调用时的压栈,跳转和返回的开销