将0转为无效

Arm*_*yan 11 c c++ macros void

在我的C++实现(Visual Studio 2008实现)中,我看到以下行 <cassert>

#ifdef  NDEBUG
#define assert(_Expression) ((void)0)
Run Code Online (Sandbox Code Playgroud)

我不明白需要将0转换为void.在我看来,这

#ifdef  NDEBUG
#define assert(_Expression) (0)
Run Code Online (Sandbox Code Playgroud)

甚至简单地说

#ifdef  NDEBUG
#define assert(_Expression) 0
Run Code Online (Sandbox Code Playgroud)

考虑到assert(expr)可以使用的背景,会做什么.

那么,什么是类型的0危险INT而不是类型0 无效在这种情况下?任何现实的例子?

Ker*_* SB 22

复杂表达式的唯一目的(void)0是避免编译器警告.如果你只是一个裸露的,无用的表达式,编译器可能会警告一个无效的表达式.但通过明确地向void你投射某些东西表明你的意思是这样做.

(如果编译器突然说"警告:表达式0;没有效果.",当你所做的一切都切换到发布模式时,想想它会给用户带来多么混乱.)

这也是C中的常见做法,您(void)printf("Hello");可以告诉编译器您有意选择忽略函数的返回值.

(void)投是不是由特定的实现仅仅是一种选择; 它是C标准所要求的.引用2011 ISO C标准(类似的措辞出现在1990年和1999年版本中):

如果NDEBUG在源文件中<assert.h>包含的assert宏定义为宏名称,则将宏定义为

#define assert(ignore) ((void)0)

C++标准要求<cassert>标题的内容与标准C <assert.h>标题相同.

  • 在`assert`的上下文中还有另一个原因:它确保"`foo = assert(blurf);`"在调试和释放模式下都会引发编译时错误. (10认同)
  • 不要忘记`assert()`需要通过标准扩展为"void表达式".我确信该要求符合标准,原因与此处的许多评论一致.但就具体实施而言,这是必要的所有理由. (4认同)