C++将函数实现为宏的优点/缺点

bso*_*aid 4 c++ macros

将业务逻辑功能实现为宏是一个好主意吗?

我继承了一些遗留的c ++代码,我发现很多业务逻辑函数都是作为冗长的神秘宏实现的.

宏是否优于函数?使用宏的一般原理是什么?

什么样的逻辑最适合宏?

这是代码中的一个简单示例

#define INSERT_VALUES(IN,ID,EO)     {\
                                        double evaluationOutput = EO;\
                                        int controls = 0;\
                                        int input_controls = m_input_controls[IN];\
                                        if(m_value_list[IN].ShouldProcess())\
                                            {\
                                            evaluationOutput = m_evaluationOutput[IN];\
                                            controls = m_controls[IN];\
                                            }\
                                        VALUE_EXIST(evaluationOutput,controls,input_controls,IN,ID,Adj);\
                                        m_evaluationOutput[IN] = controls > 0 ? evaluationOutput : 0.0;\
                                        m_controls[IN] = controls;\
                                        m_input_controls[IN] = input_controls;\
Run Code Online (Sandbox Code Playgroud)

}

Gna*_*wme 7

Effective C++中,Scott Meyers在第2项中指出:

身高consts,enumsinlines#defines

Meyers特别提到了编写宏而不是函数的做法,他说:

#define指令的另一个常见(错误)用法是使用它来实现看起来像函数但不会产生函数调用开销的宏.

像这样的宏有很多缺点,只是考虑它们是痛苦的.

幸运的是,你不必忍受这种废话.通过使用内联函数的模板,您可以获得宏的所有效率以及常规函数的所有可预测行为和类型安全性.

[实际功能]遵守范围和访问规则.例如,谈论一个类是私有的内联函数是很有意义的.一般来说,宏没有办法做到这一点.

要具体回答你的问题:

  • 一些程序员编写宏而不是函数来避免函数调用的感知开销 - 这种可疑的实践通常几乎没有可衡量的好处.
  • 程序员过去常常使用预处理器来生成样板代码(也许还可以).在现代C++中,处理器的使用应限于#include和(可能)#ifdef/ #ifndef用于条件编译.

正如迈耶斯在结束时所说:

目前还没有时间退出预处理器,但你绝对应该给它长时间的假期.


ssu*_*ube 6

不,它们绝对不是功能的一般替代品.

宏能够处理代码本身不具备的功能,特别是在编译之前创建和修改令牌(代码).

作为交换,他们失去了所有类型的安全性,几乎所有可用于实际代码的语法糖.

当你必须做一些代码无法完成的事情,或者需要有条件地存在代码(超级调试诸如内存跟踪之类的东西)时,宏会派上用场.它们在提供更简洁或更易读的方式来处理特定事物方面也有一定的价值(一个常见的例子是#define SUCCESS(x) (x >= 0).但是,对于任何需要类型安全,异常捕获或由不常用的常用代码组成的内容在编译时变异,它们几乎永远不合适.大多数似乎可能是宏的代码可能在实际代码中更安全地表达,这对业务逻辑很重要.

您可以获得的最接近的经验法则是在编译期间是否需要发生某些事情或更改.如果是这样,请考虑使用宏,否则只需编写代码即可.请记住,模板算作代码,可以做很多你可能想要使用宏的东西,但可能会更安全一些.

  • 宏既不提供也不强制执行任何类型的安全.处理宏后,标准规则适用,但不适用于宏; 这最终成为使用它们的常见问题.没有任何地方声明或暗示宏不能生成符合类型系统的代码,但它们本身完全在系统之外并且没有固有的安全检查. (3认同)
  • 它不提供任何类型*安全*.宏可以在简单的文本搜索和替换(或多或少)上运行,完全超出语言的安全规则.例如,模板被编译和类型检查(错误消息可能同样神秘).我在使用宏时遇到的大多数有趣问题都是类型相关或来自错误间距/调用的聪明新符号. (2认同)