繁体   English   中英

C中的宏与函数之间的区别与指令存储器和速度有关

[英]Difference between macros and functions in C in relation to instruction memory and speed

根据我的理解,宏和函数之间的区别在于宏调用将被定义中的指令替换,而函数执行整个push,branch和pop -thing。 这是对的,还是我理解错了?

另外,如果这是正确的,那就意味着,宏会占用更多空间,但会更快(因为缺少推送,分支和弹出指令),不是吗?

如果C编译器没有进行优化,那么您所写的关于性能影响的内容是正确的。 但优化编译器可以内联函数就像它们是宏一样,因此内联函数调用以与宏相同的速度运行,并且没有推/弹开销。 要触发内联,请在编译器设置中启用优化(例如gcc -O2 ),并将函数作为static inline函数放到.h文件中。

请注意,有时内联/宏更快,有时真正的函数调用更快,具体取决于代码和编译器。 如果函数体非常短(并且大部分将被优化掉),通常内联比函数调用更快。

另一个重要区别是宏可以接受不同类型的参数,并且宏定义可以对多种类型有意义(但编译器不会为您进行类型检查,因此如果使用的话,可能会出现不需要的行为或隐藏的错误消息宏与错误的参数类型)。 这种多态性很难模仿C中的函数(但在C ++中很容易使用函数重载和函数模板)。

这可能是在20世纪80年代,但现代编译器要好得多。

函数并不总是推送和弹出堆栈,特别是如果它们是叶函数或具有尾调用。 此外,函数通常是内联的,即使它们是在其他转换单元中定义的,也可以内联(这称为链接时优化)。

但你是对的,一般情况下, 当关闭优化时,内联宏并且不会内联函数。 两个版本可能占用更多空间,这取决于宏/功能的细节。

函数以两种方式使用空间:正文使用空格,函数调用使用空格。 如果函数体非常小,它实际上可以节省空间来内联它。

是的,你的理解是对的。 但是你还应该注意, 没有类型检查宏,它可能导致副作用 在括号宏中你也应该非常小心。

你的理解是正确的。 关键是在编译之前解析宏。 您应该将它们视为复杂的文本替换工具(它过于简单化,但主要是它归结为它)。

所以不同之处在于,在构建过程中使用了代码。

这与编译器在创建最终二进制代码时对其真正做了什么的问题是正交的 或多或少地自由地做任何它认为正确的事情来产生预期的行为。 在C ++中,您只能使用inline关键字来提示您的偏好。 编译器可以自由地忽略该提示。

同样,这与整个预处理器业务正交。 毕竟,没有什么可以阻止你编写使用inline关键字导致C ++代码的宏。 同样,没有人会阻止你编写宏,导致很多递归的C ++函数,即使你想做,编译器也可能无法内联。

结论是你的问题是错误的。 这是一个普遍的问题,即具有大量内联函数的二进制文件与具有大量实函数调用的二进制文件。 宏只是一种技术可以用来影响这种或那种方式的权衡,你会问自己没有宏的同样的一般问题。

内联函数将始终以速度换空间的假设是错误的。 内联错误(即太大)功能甚至会对速度产生负面影响。 与这种情况一样, 不要猜测而是衡量

您应该阅读以下常见问题解答: “内联函数是否可以提高性能?”

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM