例如,采取以下措施:
#define FOO
FOO #define BAR 1
BAR
根据ANSI C和C99的每个标准,上述代码的预处理输出应该是什么?
在我看来,这应该评估为1
;但是,同时通过gcc -E
和clang -E
运行上面的示例将产生以下结果:
#define BAR 1
BAR
答案 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
有效)。