int main(void)
{
#if 0
something"
#endif
return 0;
}
上面的简单程序会在gcc中生成警告:missing terminating " character
。这看起来很奇怪,因为这意味着编译器允许#if 0
和endif
之间的代码块在此处具有无效语句,如something
,但不包含双引号"
对。使用#ifdef
和#ifndef
时会发生同样的情况。
真实评论在这里很好:
int main(void)
{
/*
something"
*/
return 0;
}
为什么呢?单引号'
的行为类似,是否还有其他特殊处理的令牌?
答案 0 :(得分:9)
在ANSI C下,“关闭”#if,#ifdef或#ifndef中的文本仍必须包含“有效的预处理令牌”。这意味着字符“和”必须与实际C代码一样配对,并且对不能跨越线边界。
答案 1 :(得分:2)
在生成可执行二进制文件之前,编译需要经历多个周期。
您尚未加入编译器。您的预处理器正在标记此错误。这不会检查C语言的语法,但是缺少引号,大括号等等都是预处理器错误。
在预处理器通过之后,您的代码将转到C编译器,它将检测您期望的错误...
答案 2 :(得分:1)
预处理器在令牌级别工作,字符串文字被视为单个令牌。预处理器警告您有一个无效的令牌。
根据C99标准,预处理令牌就是其中之一:
该标准还说:
如果'或'字符与最后一个类别匹配,则行为为 理解过程科幻奈德。
上面的“语句”之类的内容对C编译器无效,但它是一个有效的标记,并且预处理器在它到达编译器之前就消除了这个标记。
答案 3 :(得分:0)
除了凯文的回答,Incompatibilities of GCC说:
GCC抱怨失败的预处理条件中的未终止字符常量。有些程序的英文评论附在条件中,但保证会失败;如果这些评论包含撇号,GCC可能会报告错误。例如,此代码会产生错误:
#if 0 You can't expect this to work. #endif
解决此类问题的最佳方法是将文本放入由
/*...*/
分隔的实际C注释中。