在预处理指令之前的空宏的标准行为

时间:2018-11-18 07:50:21

标签: c c-preprocessor preprocessor

例如,采取以下措施:

#define FOO
FOO #define BAR 1
BAR

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

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

    #define BAR 1
BAR

3 个答案:

答案 0 :(得分:1)

您的代码无效

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

  

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

答案 1 :(得分: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 :(得分:0)

此示例实际上发生在标准(C17 6.10 / 8)中:

  

示例:

#define EMPTY
EMPTY # include <file.h>
     

第二行中的预处理标记序列不是预处理指令,因为它在翻译阶段4的开始时不是以#开头,即使它在宏{{1之后}}已被替换。

因此,您从EMPTY中看到的输出是正确的。 (注意:此处的空白量并不重要,在翻译阶段,程序已被翻译为一系列预处理令牌;输出中不同的空白量只是如何处理gcc -E有效)。