为什么C预处理程序试图解析#if 0块内的引号?

时间:2019-04-18 13:50:09

标签: c-preprocessor

demo.c:

#if 0
What's the problem?
#endif

这会产生(gcc)

demo.c:2:5: warning: missing terminating ' character
 What's the problem?
     ^

但这会编译:

#if 0
What{s the problem?
#endif

为什么编译器试图编译撇号?我认为#if 0 ... #endif中的内容将被跳过。并不是块的其余内容都可以编译。

发生了什么事?

1 个答案:

答案 0 :(得分:1)

编译器不会在条件为false的条件包含内进行 parse 文本,但是会:

  • 解释三元组(已弃用,但仍在标准中)

  • 以连续字符结尾的组合行

  • 用空格替换注释

  • 将结果文本划分为预处理令牌

  • 识别预处理指令。

(有关详细说明,请参见C标准的§5.1.1.2 Translation Phases。)

由于令牌化是在预处理之前进行的,因此即使在显然不包含在内的有条件包含的块中,注释,字符文字和字符串文字也必须正确终止(#if 0)。

除其他外,这意味着您可以将#放在注释和字符串文字中,而不必担心将它们解释为预处理器指令。 (C没有多行字符串文字,但是C ++却有,将来的C版本也可能会效仿。)

在处理了预处理指令之后,(单独地)将结果流中的预处理令牌重新解释为程序令牌,将空白丢弃,合并连续的字符串文字,并解析令牌流。