据我所知,这在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++?
发布于 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
定义,即使它们从未用于声明具有外部链接的对象或翻译单元之间的“共享”。
发布于 2018-05-30 02:48:57
区别与其说在于名称,不如说在于存在;结构定义并不存储在任何地方,其名称仅在编译期间存在。
(程序员有责任确保在使用相同名称的结构时没有冲突。否则,我们亲爱的老朋友不确定的行为会打电话来。)
另一方面,函数需要存储在某个地方,如果它有外部链接,则链接器需要它的名称。
如果你把你的函数设为static
,那么它们在各自的编译单元之外是“不可见的”,链接错误就会消失。
发布于 2018-05-30 03:06:11
若要对链接器隐藏函数定义,请使用关键字static。
foo.c
static int foo() {
return 1;
}
bar.c
static int foo() {
return 0;
}
https://stackoverflow.com/questions/50590782
复制相似问题