首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >作用域中的结构与函数定义

作用域中的结构与函数定义
EN

Stack Overflow用户
提问于 2018-05-30 02:31:21
回答 3查看 2.4K关注 0票数 29

据我所知,这在C中是合法的:

foo.c

struct foo {
   int a;
};

bar.c

struct foo {
    char a;
};

但是同样的事情对于函数来说是非法的:

foo.c

int foo() {
    return 1;
}

bar.c

int foo() {
    return 0;
}

并将导致链接错误(函数foo的多个定义)。

为什么会这样呢?结构名称和函数名称之间的区别是什么使得C不能处理其中一个而不能处理另一个?此外,此行为是否扩展到C++?

EN

回答 3

Stack Overflow用户

发布于 2018-05-30 02:49:55

您的函数定义都声明了一个名为foo的具有外部链接的实体,而C标准规定具有外部链接的实体不能有多个定义。您定义的结构类型不是具有外部链接的实体,因此您可以有多个struct foo定义。

如果您使用相同的名称声明了具有外部链接的对象,那么这将是一个错误:

foo.c

struct foo {
   int a;
};
struct foo obj;

bar.c

struct foo {
    char a;
};
struct foo obj;

现在您有两个名为obj的对象,这两个对象都有外部链接,这是不允许的。

即使只声明了其中一个对象,而没有定义,它仍然是错误的:

foo.c

struct foo {
   int a;
};
struct foo obj;

bar.c

struct foo {
    char a;
};
extern struct foo obj;

这是未定义的,因为obj的两个声明引用相同的对象,但它们没有兼容的类型(因为struct foo在每个文件中的定义不同)。

C++具有类似但更复杂的规则,用于说明inline函数和inline变量、模板以及其他C++特性。在C++中,相关的要求被称为单一定义规则(或ODR)。一个值得注意的区别是,C++甚至不允许两个不同的struct定义,即使它们从未用于声明具有外部链接的对象或翻译单元之间的“共享”。

票数 13
EN

Stack Overflow用户

发布于 2018-05-30 02:48:57

区别与其说在于名称,不如说在于存在;结构定义并不存储在任何地方,其名称仅在编译期间存在。

(程序员有责任确保在使用相同名称的结构时没有冲突。否则,我们亲爱的老朋友不确定的行为会打电话来。)

另一方面,函数需要存储在某个地方,如果它有外部链接,则链接器需要它的名称。

如果你把你的函数设为static,那么它们在各自的编译单元之外是“不可见的”,链接错误就会消失。

票数 3
EN

Stack Overflow用户

发布于 2018-05-30 03:06:11

若要对链接器隐藏函数定义,请使用关键字static。

foo.c

    static int foo() {
        return 1;
    }

bar.c

    static int foo() {
        return 0;
    }
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50590782

复制
相关文章

相似问题

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