此代码导致编译错误“error:'p‘以不同的类型重新定义”:
void fun() {
printf("fun");
}
void (*p)();
p = &fun;但如果修改
void (*p)(); p = &fun; to
void (*p)() = &fun,一切都很好
两者的区别是什么
void (*p)(); p = &fun;和
void (*p)() = &fun
发布于 2012-07-15 23:06:29
前面的三个答案没有回答这个问题,当它们表明“p=&fun;”是一个任务时,它们是不正确的。
实际上,编译器试图将“p=&fun;”解释为一个声明,因此“p”是一个声明符,“&fun”是一个初始化器,而“p=&fun”则形成一个初始声明符(在C规范的形式语法中)。
将其解释为声明后,声明中应该包含的类型默认为int (由于遗留原因),因此编译器实际上将其视为“int p =&fun;”,这是p的定义。因为p以前被定义为指向函数的指针,所以编译器会抱怨您正在用不同的类型重新定义p。
对于语言语法学家:我不明白这怎么会是形式语法中的声明。翻译单元将扩展为外部声明,外部声明将扩展为声明,声明将扩展为“声明说明符init-声明符-listopt;”(根据C标准中的6.7 )。声明说明符似乎至少需要存储类说明符、类型说明符、类型限定符或函数说明符中涉及的关键字中的一个。源代码中没有出现这样的关键字,因此这不能是一个声明。我怀疑编译器正在使用1999年标准之前的一些语法进行解析,所以这是遗留行为。尽管如此,错误消息清楚地表明编译器已经看到了两个定义,而不是后面跟着赋值的定义。
发布于 2012-07-15 22:36:47
您不能在全局范围内执行任意赋值;请尝试:
void fun() {
printf("fun");
}
void (*p)();
int main(void) {
p = &fun;
return 0;
}void (*p)() = &fun;之所以能工作,是因为您正在创建和初始化一个变量。允许在全局范围内进行初始化。void (*p)(); p = &fun;创建一个未初始化的变量,然后为其赋值。赋值的处理方式与初始化不同,需要在某个函数内部执行。
发布于 2012-07-15 22:42:20
void (*p)(); // This is a declaration和
void (*p)() = &fun; // This is also a declaration都是声明。
p = &fun; // This is a statement是一句话。语句不是声明(声明也不是语句)。
您不能在文件范围内使用语句。C语言只允许有块作用域的语句。
https://stackoverflow.com/questions/11492731
复制相似问题