过度依赖宏

Sam*_*yon 16 c c++ macros

我觉得,每次我读C或C++程序时,其中一半或更多只是宏.我知道宏可以很酷但是它们很难跟踪,调试等.更不用说大多数编程语言甚至都没有定义像宏这样的东西(尽管Perl6会有类似的东西).

我个人总是找到一种方法来编写我的代码而不使用宏,无论是模板,多重继承等.我甚至觉得我不是一个优秀的程序员,因为所有的专业人员使用宏,我尽量避免使用它们如我所能.

问题是,如果没有宏,是否存在无法解决的问题?宏最终是一个好/坏的做法?我什么时候应该考虑使用宏?

sha*_*oth 18

是的,这是一个.当您需要将跟踪代码添加到程序中时,一个配置包含它而另一个完全省略,您必须使用宏.

就像是:

#ifdef WITH_LOGGING
    #define LOG( x ) DoLog( x )
#else
    #define LOG( x )
#endif
Run Code Online (Sandbox Code Playgroud)

现在你用这种方式使用它:

LOG( L"Calling blahblahblah with " + getSomeStringHardToCompute() );
Run Code Online (Sandbox Code Playgroud)

并且在配置中WITH_LOGGING你有这个代码,否则它被完全省略 - 甚至不存在于二进制文件中,因此

  • 它无法帮助其他人分析您的程序
  • 你得到一个较小的二进制
  • 该程序根本不会浪费时间
  • 编译器可以生成更好的优化代码.

  • @Basilevs:函数需要参数计算.在上面的例子中,如果使用函数调用,无论如何都将调用`getSomeStringHardToCompute()`.宏是消除它的唯一方法. (3认同)
  • @thomasrutter:是的,你可以,但那太可怕了 - 你会严重污染有用的代码. (2认同)
  • @Basilevs:编译器知道它编译的每种类型的所有内容.为什么这有关系?如果评估参数有副作用,则无法对其进行优化,或者编译器会更改程序的语义. (2认同)

Dum*_*der 10

直接来自Scott Myer的Effective C++ - > 1

鉴于可用性和内联的可用性,您对预处理器的需求减少了,但并未完全消除.当你放弃#include时,这一天远非如此,#ifdef/#ifndef继续在控制编译方面发挥重要作用.目前还没有时间退出预处理器,但你绝对应该计划开始更长时间的假期.


小智 9

你一直在看一些糟糕的C++代码.我使用宏的地方仅限于:

  • 头卫
  • 非常偶然的条件编译
  • 投掷宏的一般例外
  • 一般调试/日志输出宏

我不认为这四个是可以避免的.

  • 特别是因为对于日志记录/投掷,您通常希望自动提取文件名和行号. (3认同)