请考虑以下代码:
#if 0
#foobar
#endif
在这种情况下,预处理器不会抱怨#foobar
不是有效的预处理器指令。由于#if 0
,它只是跳过块,代码编译得很好。
现在考虑以下代码:
#if 0
#if 1
#endif
在这种情况下,预处理器突然抱怨缺少#endif
指令。这让我感到困惑,因为它表明,即使在#if 0
的情况下,预处理器似乎也不会完全忽略#if 0
块中的内容。似乎#if
指令仍然被解析,预处理器甚至会强制执行它们的正确性,即每个#if
都需要与#endif
匹配,即使在跳过的块中也是如此。
以前,我的印象是使用#if 0
/ #endif
封装块相当于使用/*
和*/
对其进行评论。但显然事实并非如此。
因此我的问题是:
这种设计背后的理由是什么?为什么预处理器强制执行正确匹配的#if
指令,即使在使用#if 0
等某些指令明确告知预处理器跳过的块中?
在#if 0
块中处理哪些完全指令?如上例所示,预处理器不会抱怨#foobar
之类的无效预处理程序指令,但它会抱怨无法匹配的#if
指令。那么哪些预处理程序指令实际上是在#if 0
块中处理的?只有#if
/ #ifdef
/ #elif
/ #else
/ #endif
或者是否有更多指令在#if 0
块中处理?
答案 0 :(得分:7)
仅处理可能更改控制流的指令。其余的,如#foobar
,将被忽略 1 。
1 (引用自:ISO / IEC 9899:201x 6.10.1条件包含6)
按顺序检查每个指令的条件。如果它的计算结果为false(零),则为该组
跳过它控制的指令:仅通过确定的名称处理指令
该指令是为了跟踪嵌套条件的级别;剩下的
指令的预处理标记被忽略,其他预处理标记也被忽略
组