当X未定义时,为什么没有"#if X"警告?

Mic*_*ick 21 c++ visual-studio-2008 c-preprocessor

我偶尔会编写类似这样的代码:

// file1.cpp
#define DO_THIS 1

#if DO_THIS
    // stuff
#endif
Run Code Online (Sandbox Code Playgroud)

在代码开发期间,我可以切换DO_THIS0到1之间的定义.

最近我不得不重新安排我的源代码并将一些代码从一个文件复制到另一个文件.但我发现我犯了一个错误,这两个部分已经分开了:

// file1.cpp
#define DO_THIS 1
Run Code Online (Sandbox Code Playgroud)

// file2.cpp
#if DO_THIS
    // stuff
#endif
Run Code Online (Sandbox Code Playgroud)

显然我修正了错误,但后来想到了自己,为什么编译器没有警告我?我的警告级别设置为4. #if X当X未定义时,为什么不可疑?

还有一个问题:如果我在其他地方犯了同样的错误,是否有任何系统的方法可以找出?这个项目很大.

编辑:我可以理解#ifdef没有任何警告是完全合理的.但肯定#if是不同的.

Bil*_*ill 31

gcc可以为此生成警告,但标准可能不需要它:

-Wundef
如果在`#if'指令中计算未定义的标识符,则发出警告.

  • 它也是安全关键编码标准的常见规则. (2认同)

AnT*_*AnT 17

同样,正如经常发生的那样,"为什么"问题的答案只是:它是以这种方式完成的,因为前一段时间它决定这样做.当你使用一个未定义的宏时,#if它被替换为0.你想知道它是否实际定义 - 使用defined()指令.

但是,"默认为0"方法有一些有趣的好处.特别是当您使用可能由平台定义的宏时,而不是您自己的宏.

例如,某些平台提供宏__BYTE_ORDER,__LITTLE_ENDIAN__BIG_ENDIAN确定它们的字节顺序.您可以编写预处理器指令

#if __BYTE_ORDER == __LITTLE_ENDIAN
  /* whatever */
#else
  /* whatever */
#endif
Run Code Online (Sandbox Code Playgroud)

但是如果你试图在一个根本没有定义这些非标准宏的平台上编译这个代码(即对它们一无所知),上面的代码将由预处理器转换成

#if 0 == 0
...
Run Code Online (Sandbox Code Playgroud)

并且代码的little-endian版本将"默认"编译.如果你把原#if作为

#if __BYTE_ORDER == __BIG_ENDIAN
...
Run Code Online (Sandbox Code Playgroud)

那么代码的big-endian版本将被"默认"编译.

我不能说这#if被定义为特别适用于上述技巧,但它有时很有用.

  • 我在谈论`#if defined(<macro>)`.在MSDN中它应该在`#if`下.也许它被恰当地称为"操作员",而不是"指令". (2认同)