#if 0和#endif之间的代码块必须配对双引号?

int main(void) { #if 0 something" #endif return 0; } 

上面一个简单的程序生成一个警告: missing terminating " character gcc中的missing terminating " character 。这看起来很奇怪,因为这意味着编译器允许#if 0endif之间的代码块在这里有无效的语句,但不是双引号"对。 使用#ifdef#ifndef

真实的评论在这里很好:

 int main(void) { /* something" */ return 0; } 

为什么? 并且单引号'表现相似,是否还有其他特殊处理的令牌?

请参阅comp.Lang.c FAQ,11.19 :

在ANSI C下,“关闭”#if,#ifdef或#ifndef中的文本仍必须包含“有效的预处理标记”。 这意味着字符“和”必须与实际C代码一样配对,并且对不能跨越线边界。

在生成可执行二进制文件之前,编译需要经历多个周期。

你还没有编译器。 您的预处理器正在标记此错误。 这不会检查C语言语法,但缺少引号,大括号等事情是预处理器错误。

在预处理器通过之后,您的代码将转到C编译器,它将检测您期望的错误…

预处理器在令牌级别工作,字符串文字被视为单个令牌。 预处理器警告您有一个无效的令牌。

根据C99标准,预处理令牌是以下之一:

  • 头名
  • identi网络呃
  • PP-数
  • 字符常量
  • 字符串字面量
  • 标点符号
  • 每个非白色空格字符不能是上述之一

该标准还说:

如果’或’字符与最后一个类别匹配,则行为未定义。

上面的“语句”之类的东西对C编译器是无效的,但它是一个有效的标记,并且预处理器在它到达编译器之前消除了这个标记。

除了凯文的回答, 海湾合作委员会的不相容性说:

GCC抱怨失败的预处理条件中的未终止字符常量。 有些程序的英文评论附在条件中,但保证会失败; 如果这些评论包含撇号 ,GCC可能会报告错误。 例如,此代码会产生错误:

 #if 0 You can't expect this to work. #endif 

解决此类问题的最佳方法是将文本放入由/*...*/分隔的实际C注释中。