最近我开始查看他们正在使用的嵌入式代码
#define print() printf("hello world")
Run Code Online (Sandbox Code Playgroud)
代替
void print() { printf("hello world"); }
Run Code Online (Sandbox Code Playgroud)
我的问题是使用#define而不是创建函数有什么好处?
它可能与性能有关.
函数调用有一些开销(即调用,保存堆栈,返回等),而宏是宏名称直接替换它的内容(即没有开销).
在这个例子中,函数foo和bar函数完全相同.foo使用bar函数调用时使用宏.
正如你所看到的bar,printY在一起需要更多指令foo
.
因此,通过使用宏,性能变得更好.
但是......这种方法存在缺点:
宏很难调试,因为您无法单步执行宏
广泛使用宏会增加二进制文件的大小(与使用函数调用相比).可以在负面方向影响性能的东西.
另请注意,现代编译器(具有优化功能)非常善于确定何时自动内联函数是一个好主意(即您的代码是使用函数调用编写的,但编译器决定将函数内联,就好像它是一个宏).因此,您可以使用函数调用获得相同的性能.
此外,您可以使用inline关键字作为编译器的提示,您认为内联函数是一件好事.但即使使用该关键字,编译器也可能决定不内联.确保代码内联的唯一方法是使用宏.
没有什么优势。#define像这样使用是相当古老的 C 编程风格。
1999 年,C 语言获得了inline使所有此类宏过时的关键字。对于现代编译器来说,inline这通常也是多余的,因为现在编译器在确定何时内联方面比程序员更好。
不过,一些嵌入式编译器在此类优化方面仍然相当糟糕,这就是嵌入式 C 代码在现代化方面往往落后的原因。
一般来说,像这样进行微优化被称为“过早优化”,这意味着程序员正在干预他们应该留给编译器的优化。即使在硬实时系统中也是如此。只有当您 1) 检测到实际瓶颈,2) 进行反汇编以查看手动内联是否确实对性能有好处时,优化才应该是最后的手段。