当前位置:  开发笔记 > 编程语言 > 正文

何时在C中使用类似函数的宏

如何解决《何时在C中使用类似函数的宏》经验,为你挑选了2个好方法。

今天晚上我正在阅读一些用C编写的代码,文件顶部是类似函数的宏HASH:

#define HASH(fp) (((unsigned long)fp)%NHASH)

这让我想知道,为什么有人会选择使用类似函数的宏来实现这种函数,而不是将它作为常规的vanilla C函数实现?每种实施的优缺点是什么?

谢谢你!



1> Bob Murphy..:

这样的宏可以避免函数调用的开销.

看起来似乎并不多.但在您的示例中,宏将变为1-2个机器语言指令,具体取决于您的CPU:

获取fp的内存值并将其放入寄存器中

取寄存器中的值,按固定值进行模数(%)计算,并将其保留在同一寄存器中

而功能相当的将是更多的机器语言指令,通常是类似的

将fp的值粘贴在堆栈上

调用该函数,该函数还将下一个(返回)地址放在堆栈上

也许在函数内部构建一个堆栈框架,具体取决于CPU架构和ABI约定

从堆栈中获取fp的值并将其放入寄存器中

取寄存器中的值,按固定值进行模数(%)计算,并将其保留在同一寄存器中

也许从寄存器中获取值并将其放回堆栈,具体取决于CPU和ABI

如果构建了堆栈框架,请将其展开

将返回地址弹出堆栈并继续执行指令

还有更多代码,嗯?如果你正在做一些事情,比如在GUI中的窗口中渲染成千上万个像素中的每个像素,那么如果使用宏,事情运行得更快.

就个人而言,我更喜欢使用C++内联作为更具可读性和更不容易出错的内容,但内联也更多地是对编译器的暗示,它不必采取.预处理器宏是编译器无法争辩的大锤.


当然,C99现在已经十年了.任何不支持它的C编译器都会严重过时.
@ liw.fi:告诉微软!
这就是内联函数的用途!:)

2> AnT..:

基于宏的实现的一个重要优点是它不依赖于任何具体的参数类型.C语言中的函数式宏在很多方面都是C++中的模板函数(C++中的模板诞生为"更文明"的宏,BTW).在这种特殊情况下,宏的参数没有具体类型.它可能绝对是任何可转换为类型的东西unsigned long.例如,如果用户如此满意(并且如果他们愿意接受实现定义的结果),他们可以将指针类型传递给此宏.

无论如何,我不得不承认这个宏不是宏的类型独立灵活性的最好例子,但总的来说,灵活性经常被派上用场.同样,当某个功能由某个功能实现时,它仅限于特定的参数类型.在许多情况下,为了将类似的操作应用于不同的类型,有必要提供具有不同类型的参数的几个函数(和不同的名称,因为这是C),而同样可以通过仅一个类似函数的宏来完成.例如,宏

#define ABS(x) ((x) >= 0 ? (x) : -(x))

与所有算术类型的作品,而基于函数的实现必须提供相当多的人(我暗示标准abs,labs,llabsfabs).(是的,我知道传统上提到的这种宏的危险.)

宏并不完美,但关于"由于内联函数而不再需要类似函数的宏"的流行格言只是简单的无稽之谈.为了完全替换类似函数的宏,C将需要函数模板(如在C++中)或至少需要函数重载(如在C++中那样).如果没有那个类似函数的宏,并且仍将是C中非常有用的主流工具.

推荐阅读
和谐啄木鸟
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有