最近我要查看嵌入式代码,因为它们正在使用
#define print() printf("hello world")
代替
void print() { printf("hello world"); }
我的问题是使用#define
而不是创建函数有什么好处?
答案 0 :(得分:9)
这可能与性能有关。
函数调用会产生一些开销(即调用,将内容保存在堆栈上,返回等),而宏是使用其内容直接替换宏名称(即没有开销)。
在此示例中,功能foo
和bar
的功能完全相同。 foo
使用宏,而bar
使用函数调用。
如您所见,bar
和printY
一起比foo
需要更多的指令
。
因此,通过使用宏,性能会好一些。
但是...这种方法有缺点:
宏很难调试,因为您不能单步执行宏
广泛使用宏会增加二进制文件的大小(与使用函数调用相比)。可能会对性能产生负面影响的东西。
还要注意,现代编译器(启用了优化功能)非常擅长于确定何时自动内联函数是一个好主意(即,您的代码是使用函数调用编写的,但是编译器决定像内联那样内联函数)是一个宏)。因此,使用函数调用可能会获得相同的性能。
此外,您可以使用inline
关键字作为向编译器的提示,以为您认为内联函数会很好。但是即使使用该关键字,编译器也可能决定不内联。确保代码内联的唯一方法是使用宏。
答案 1 :(得分:3)
没有优势。像这样使用#define
是相当古老的C编程风格。
在1999年,C语言使用了inline
关键字来使所有这些宏都过时了。对于现代编译器,inline
常常也是多余的,因为在确定何时内联时,如今的编译器要比程序员好。
尽管如此,某些嵌入式编译器在这种优化上仍然会很糟糕,这就是为什么嵌入式C代码在现代化方面往往会落后的原因。
通常,进行这样的微优化称为“过早的优化”,这意味着程序员正在干预应该留给编译器的优化。即使在硬实时系统中。只有在以下情况下,优化才是最后的选择:1)检测到实际瓶颈,并且2)进行分解以查看手动内联是否确实对性能有任何好处。
答案 2 :(得分:3)
有时您想在编译时添加功能。宏为您提供了一种简便的方法。