【问题标题】:Standard Behavior Of An Empty Macro Preceding A Preprocessing Directive预处理指令之前的空宏的标准行为
【发布时间】:2018-11-18 07:50:21
【问题描述】:

举个例子:

#define FOO
FOO #define BAR 1
BAR

根据 ANSI C 和 C99 标准,上述代码的预处理输出应该是什么?

在我看来,这应该评估为1;但是,通过gcc -Eclang -E 运行上述示例会产生以下结果:

    #define BAR 1
BAR

【问题讨论】:

  • # 应该是指令行中的第一个非空格字符,否则会被忽略
  • @qrdl:它不会被忽略:它会产生错误,因为# 在预处理后不是有效的令牌。
  • @rici 显然编译器会抱怨它,但是 OP 在这里只谈论 CPP,而 CPP 忽略它。

标签: c c-preprocessor preprocessor


【解决方案1】:

标准草案“ISO/IEC 9899:201x 委员会草案 — 2011 年 4 月 12 日 N1570”第 6.10 节实际上包含了一个示例:

示例:

#define EMPTY 
EMPTY # include <file.h>

第二行的预处理标记序列不是预处理指令,因为它在翻译阶段 4 开始时不以 # 开头,即使它会在宏 EMPTY 被替换后这样做。

它告诉我们“...第二行不是预处理指令...”

所以对于你的代码

FOO #define BAR 1

不是预处理指令,意味着只有 FOO 将被替换,而 BAR 将被定义。因此预处理器的输出是:

 #define BAR 1
BAR

【讨论】:

    【解决方案2】:

    您的代码无效

    ISO/IEC 9899:2011,第 6.10 节预处理指令:

    预处理指令由一系列预处理组成 满足以下约束的标记:第一个标记 该序列是一个 # 预处理标记,它(在 翻译阶段 4) 是源文件中的第一个字符 (可选在不包含换行符的空格之后)或 跟在包含至少一个换行符的空格之后。

    【讨论】:

      【解决方案3】:

      这个例子实际出现在标准(C17 6.10/8)中:

      示例:

      #define EMPTY
      EMPTY # include <file.h>
      

      第二行的预处理标记序列不是预处理指令,因为它在翻译阶段 4 开始时不是以 # 开头的,尽管它会在宏 EMPTY 之后这样做换了。

      所以您从gcc -E 看到的输出是正确的。 (注意:这里的空白数量并不重要,在翻译的那个阶段,程序已被翻译成一系列预处理标记;输出中不同数量的空白只是如何处理的人工制品gcc -E 有效)。

      【讨论】:

      • 也谢谢你,但很遗憾,我只能接受一个答案,而且 4386427 太快了。 :)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-07
      相关资源
      最近更新 更多