为什么C预处理器不会忽略它跳过的块中的无效指令?

时间:2016-12-25 17:27:36

标签: c c-preprocessor

请考虑以下代码:

#if 0
   #foobar
#endif

在这种情况下,预处理器不会抱怨#foobar不是有效的预处理器指令。由于#if 0,它只是跳过块,代码编译得很好。

现在考虑以下代码:

#if 0
   #if 1
#endif

在这种情况下,预处理器突然抱怨缺少#endif指令。这让我感到困惑,因为它表明,即使在#if 0的情况下,预处理器似乎也不会完全忽略#if 0块中的内容。似乎#if指令仍然被解析,预处理器甚至会强制执行它们的正确性,即每个#if都需要与#endif匹配,即使在跳过的块中也是如此。

以前,我的印象是使用#if 0 / #endif封装块相当于使用/**/对其进行评论。但显然事实并非如此。

因此我的问题是:

  1. 这种设计背后的理由是什么?为什么预处理器强制执行正确匹配的#if指令,即使在使用#if 0等某些指令明确告知预处理器跳过的块中?

  2. #if 0块中处理哪些完全指令?如上例所示,预处理器不会抱怨#foobar之类的无效预处理程序指令,但它会抱怨无法匹配的#if指令。那么哪些预处理程序指令实际上是在#if 0块中处理的?只有#if / #ifdef / #elif / #else / #endif或者是否有更多指令在#if 0块中处理?

1 个答案:

答案 0 :(得分:7)

仅处理可能更改控制流的指令。其余的,如#foobar,将被忽略 1

1 (引用自:ISO / IEC 9899:201x 6.10.1条件包含6)
按顺序检查每个指令的条件。如果它的计算结果为false(零),则为该组 跳过它控制的指令:仅通过确定的名称处理指令 该指令是为了跟踪嵌套条件的级别;剩下的 指令的预处理标记被忽略,其他预处理标记也被忽略 组