首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么这段代码会导致编译错误"redefinition"?

为什么这段代码会导致编译错误"redefinition"?
EN

Stack Overflow用户
提问于 2012-07-15 22:31:28
回答 4查看 362关注 0票数 2

此代码导致编译错误“error:'p‘以不同的类型重新定义”:

代码语言:javascript
复制
void fun() {
    printf("fun");
}
void (*p)();
p = &fun;

但如果修改

void (*p)(); p = &fun; to

void (*p)() = &fun,一切都很好

两者的区别是什么

void (*p)(); p = &fun;

void (*p)() = &fun

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 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年标准之前的一些语法进行解析,所以这是遗留行为。尽管如此,错误消息清楚地表明编译器已经看到了两个定义,而不是后面跟着赋值的定义。

票数 1
EN

Stack Overflow用户

发布于 2012-07-15 22:36:47

您不能在全局范围内执行任意赋值;请尝试:

代码语言:javascript
复制
void fun() {
    printf("fun");
}

void (*p)();

int main(void) {
 p = &fun;
 return 0;
}

void (*p)() = &fun;之所以能工作,是因为您正在创建和初始化一个变量。允许在全局范围内进行初始化。void (*p)(); p = &fun;创建一个未初始化的变量,然后为其赋值。赋值的处理方式与初始化不同,需要在某个函数内部执行。

票数 3
EN

Stack Overflow用户

发布于 2012-07-15 22:42:20

代码语言:javascript
复制
void (*p)();   // This is a declaration

代码语言:javascript
复制
void (*p)() = &fun;  // This is also a declaration

都是声明。

代码语言:javascript
复制
p = &fun;  // This is a statement

是一句话。语句不是声明(声明也不是语句)。

您不能在文件范围内使用语句。C语言只允许有块作用域的语句。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11492731

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档