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

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

真实的评论在这里很好:

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

为什么?并且单引号的'行为类似,是否还有其他特殊处理的标记?

4

4 回答 4

9

请参阅comp.Lang.c 常见问题解答,11.19

在 ANSI C 中,“关闭”#if、#ifdef 或 #ifndef 内的文本仍必须包含“有效的预处理标记”。这意味着字符 " 和 ' 必须像在真正的 C 代码中一样每一个都成对,并且成对不能跨越行边界。

于 2013-06-22T04:17:49.857 回答
2

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

你还没有进入编译器。您的预处理器正在标记此错误。这不会检查 C 语言语法,但缺少引号、大括号和类似的东西是预处理器错误。

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

于 2013-06-22T04:15:52.860 回答
1

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

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

  • 标题名称
  • 标识符
  • pp号
  • 字符常量
  • 字符串字面量
  • 标点符号
  • 每个不能是上述之一的非空白字符

该标准还说:

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

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

于 2013-06-22T04:15:43.043 回答
0

除了凯文的回答,GCC 的不兼容性说:

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

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

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

于 2014-06-15T14:42:18.080 回答