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

时间:2013-06-22 04:06:09

标签: c

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

上面的简单程序会在gcc中生成警告:missing terminating " character。这看起来很奇怪,因为这意味着编译器允许#if 0endif之间的代码块在此处具有无效语句,如something,但不包含双引号"对。使用#ifdef#ifndef时会发生同样的情况。

真实评论在这里很好:

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

为什么呢?单引号'的行为类似,是否还有其他特殊处理的令牌?

4 个答案:

答案 0 :(得分:9)

请参阅comp.Lang.c FAQ, 11.19

  

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

答案 1 :(得分:2)

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

您尚未加入编译器。您的预处理器正在标记此错误。这不会检查C语言的语法,但是缺少引号,大括号等等都是预处理器错误。

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

答案 2 :(得分:1)

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

根据C99标准,预处理令牌就是其中之一:

  • header-name
  • identi音响ER
  • PP-数
  • character-constant
  • 字串文本
  • punctuator
  • 每个非白色空格字符,不能是其中之一 上述

该标准还说:

  

如果'或'字符与最后一个类别匹配,则行为为   理解过程科幻奈德。

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

答案 3 :(得分:0)

除了凯文的回答,Incompatibilities of GCC说:

  

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

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

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