使用C / C ++宏作为条件编译的快捷方式是一种好习惯吗?


13

假设我要在代码中包含几种类型的输出消息。其中之一是DEBUG,仅当在Debug模式下编译代码时才打印。

通常我必须写一些像

#ifdef DEBUG
    std::cout << "Debug message" << std::endl;
#endif

在许多地方使用起来非常麻烦和烦人。

为代码段定义宏是一种好习惯,这样您就可以使用它吗?

MSG_DEBUG("Debug message")

还是有没有其他更优雅的方式在没有宏的情况下如何处理它?我对C和C ++中可能的解决方案感兴趣,因为我在不同的项目中使用了这两种语言。



从这个问题尚不清楚,为什么您不只是将条件代码放在函数中并调用它。还有其他约束可以阻止这种情况吗?
亚历克斯

@gnat您提到的问题是如此广泛,以至于大多数人不会将其与该主题相关联,尤其是当他们在Internet上查找此特定问题时。
Eenoku

3
您的问题同时带有cc ++标记,但是它们是完全不同的语言。您能说明您在说什么吗?您的示例在C语言中将是完美的,但是constexpr if例如,在C ++中可能会更好地实现。
约尔格W¯¯米塔格

1
顺便说一句,诊断应该去STDERR。另外,为什么不把它依赖于NDEBUGassert()做呢?然后,您可以像定义它#define DEBUG_MSG(MSG) assert(std::cerr << MSG),它也测试流状态。
Deduplicator

Answers:


19

当然,如果您首先可以使用宏,那么通过任何一种良好的编码措施,当然最好还是定义一个参数化的宏而不是重复重复相同的条件代码。

您是否应该完全使用宏?在我看来,您应该这样做,因为它已被C接受,并且任何无宏解决方案都至少需要在调试模式之外执行某些操作。典型的C程序员会随时在不必要的运行时间上选择一个稍微难看的宏。


13

这里有一个个人喜好元素,但是在C ++中,我更喜欢在头文件中执行此操作:

#ifdef _DEBUG
    void DebugMessage(...);
#else
    inline void DebugMessage(...) {}
#endif

这样,该功能就可以在发行版本中内联了,但在调试版本中是正确的功能,因此您可以进行正确的类型检查,明智的错误消息等,并可以在以后添加其他功能(可能记录?)。

显然,您还需要将功能的相应定义封装在.cpp文件中的一个#ifdef _DEBUG块中。


但是这里仍然存在通话开销,不是吗?
Eenoku

7
如果您的编译器将生成代码以在发行版本中调用一个已知的空函数,那么要提高效率,首先要做的第一件事就是获得一个更好的编译器。这确实是微不足道的优化。
David Thornley

@Eenoku不,正如David所说,您应该使用的所有编译器都将其删除。
杰克·艾德利

3
这里有一个关键的区别:宏(取决于它的编写方式)不会评估其自变量表达式,而函数始终会。同样,将非平凡的参数传递给varargs函数也是不确定的行为(通常会触发编译器警告)。
塞巴斯蒂安·雷德尔


2

当然,只要确保您没有遵循团队给出的代码准则即可。确保系统中没有其他代码尝试通过常规if条件达到相同的功能。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.