我尝试在代码中使用#
运算符:
#include <stdio.h>
int main(void)
{
printf("hello %s !!! n", #world);
return 0;
}
使用gcc编译后,此代码会产生以下错误:
str.c: In function ‘main’:
str.c:5:27: error: stray ‘#’ in program
printf("hello %s !!! n", #world);
但是,当我定义使用此运算符的宏时,代码将被编译:
#include <stdio.h>
#define STRINGIFY(x) #x
int main(void)
{
printf("hello %s \n", STRINGIFY(world));
return 0;
}
预处理程序是否报告了此错误?如果是这样,为什么?
答案 0 :(得分:3)
因为#parameter
是宏扩展的一部分。所有这些都是在编译器甚至没有看到代码之前就由预处理器完成的。并且此令牌仅应用于宏参数。
考虑以下宏:
#define STR(x) #x
Str(Hello)
是"Hello"
但是,如果我们在代码中编写#word,则预处理器不会将其视为宏的一部分,并且 word 不是宏参数。因此,预处理器将忽略它。编译器看到相同的#word,却不知道该怎么做。因此它报告一个错误。考虑下面的预处理器文本。
#define STR(x) #x
const char * str=STR(Hello);
const char * buggy_str=#Hello;
结果将是:
const char * str="Hello";
const char * buggy_str=#Hello;
C编译器看到第一个字符串,对他来说还可以。但是,当他看到第二个字符串时,对令牌#
一无所知,从而报告了错误。
答案 1 :(得分:2)
#
字符仅在以下C程序中允许使用:
它是用C标准定义的。
在您的程序中,可以在任何这些上下文之外找到它,因此将其标记为“杂散”,并且该程序将被拒绝。
C标准没有指定哪个翻译阶段负责诊断。无论如何,它们只是概念阶段,在真正的编译器中可能无法识别。因此,关于在预处理过程中是否发出错误的问题还没有得到很好的定义。