【问题标题】:How to disable macro function?如何禁用宏功能?
【发布时间】:2011-11-16 05:16:13
【问题描述】:

当我想禁用调试检查时,是否可以将调试宏设置为空字符串? 定义 NDEBUG 时,assertBOOST_ASSERT 都设置为 ((void)0)

为什么不这样做呢?

#ifdef NDEBUG

#define MY_DEBUG_MACRO_FUNCTION(x,y,z) ""

#elif
  // define macros
#endif

【问题讨论】:

  • 您为什么更愿意将其定义为空字符串文字?
  • 如何使用这个调试宏?你能告诉我们它在哪里使用吗?
  • 空扩展和""扩展都存在here描述的问题。

标签: macros c-preprocessor


【解决方案1】:

这个想法是让宏在发布版本上什么都不做。您可以将其定义为空字符串文字,因为 ""; 是一个有效的表达式。我相信被定义为((void)0) 的原因是实现不会对表达式发出警告。我没有充分的理由这么说,但一些最小的测试表明""; 会生成警告,而((void)0) 不会。当然,警告不是标准化的,因此可能有一个特定的实现也会对((void)0) 发出警告,但它必须将assert 定义为NDEBUG 构建中没有的其他东西,否则它会对用户来说很烦人。

【讨论】:

  • 使用((void)0) 的另一个原因是,如果宏应该像函数调用一样工作——也就是说,如果MACRO(), something_else() 在调试模式下有效,它不应该在发布模式下意外中断。
【解决方案2】:

不,这不好。但是您可以将宏的“主体”设为空:

#define MY_DEBUG_MACRO_FUNCTION(x,y,z)

请注意,没有定义任何内容,因此在使用时不会将任何内容放入源代码中。

【讨论】:

  • 这与((void)0)的效果基本相同——我想不出任何情况下两者会产生不同的结果。
  • @ChrisLutz 呃什么?预处理器基本上只是一个在编译器之前运行的程序,对定义的宏进行搜索替换。将定义设为空会将宏替换为空。当然,这完全取决于宏的使用方式,提出问题的人没有解释。
  • 在替换之后,我无法想象任何地方#define MACRO() 将有效而#define MACRO() ((void)0) 无效,反之亦然:它们都服务于“没有结果的声明。 " (虽然现在我想起来了,MACRO(), something_else()#define MACRO() 来说可能是个问题,但对于#define MACRO() ((void)0) 来说仍然会按预期编译,所以我猜是有区别的。)
【解决方案3】:

按照您的主题行使用#undef。当函数有宏版本和 C 版本时,这很有用。这样您就可以在内联扩展宏上使用编译后的代码。

【讨论】:

  • 当然会 - udef 它不是 C99 处理器宏 - 你还能期待什么?
  • 哦,看——来自 C99 标准,我怀疑你读过! 6.10.3.5 宏定义的范围 1 宏定义持续(独立于块结构)直到遇到相应的#undef 指令或(如果没有遇到)直到预处理翻译单元结束。宏定义在翻译阶段 4 之后没有意义。
  • 如果你取消定义一个宏,你需要从源代码中编辑它。如果您还没有这样做,请阅读 assert.h。附言具有 C 编程知识的 PPL 不应发布答案。
  • 您能否指出 ISO/IEC 9899:1999 国际 C 语言标准中这样说的段落?你显然比我更了解 C 语言
  • 我真的希望在过去的7年里你变得不那么肆无忌惮了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多