为什么非 extern 可以出现在 C/C++ 中的 .h 文件中?
Take this file as example,there are many non-extern structures like:
struct list_head source_list;
How can it work when this header file is included by more than one compile units?
There should be error reporting that the same symbol is defined twice,right?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
从技术上讲应该存在,但这种用法已经存在多年并且不可能根除(已经尝试过;每隔一段时间,一些供应商就会决定将其设为错误,并在前一百个左右的错误报告后恢复)。迂腐地,
.h
文件应该声明extern
和 one.c
/.cpp 文件应该定义它。
简而言之,当您不指定顶级变量的链接(
static
、extern
等)时,它会被声明为“common”。在链接时,如果对该变量的所有引用都具有相同的大小(和类型,如果可用),则该变量将被分配一次,并且所有引用都将指向它。如果链接器发现同一变量有不同的大小/类型/链接,则会抛出错误。编辑:这显然让人们感到困惑。这里:
注意完全没有关于
int foo
被多重定义的错误。 这就是我一直想说的。Technically there should, but that usage has been around for years and is impossible to eradicate (it's been tried; every so often some vendor decides to make it an error, and reverts after the first hundred or so bug reports). Pedantically, the
.h
file should declare itextern
and one.c
/.cpp
file should define it.Briefly, when you don't specify the linkage (
static
,extern
, etc.) of a top level variable, it's declared as "common". At link time, if all references to that variable are the same size (and type, when available) then it is allocated once and all references are made to point to it. If the linker finds different sizes / types / linkages for the same variable, it throws an error.EDIT: this is clearly confounding people. Here:
Note the complete lack of errors about
int foo
being multiply defined. This is what I've been trying to say.这个术语是“暂定定义”:
所以这在 C 中定义得很好(但经常不被接受)。
The term for this is "tentative definition":
So this is well defined in C (but often frowned upon).
此 struct list_head source_list; 字段在其他结构内声明,因此它们不是符号。
其他(顶级)结构的声明具有不同的名称,因此也可以。
编辑
请注意,此标头中的所有变量实际上都标有
extern
。This
struct list_head source_list;
fields are declared inside other structures so they are not symbols.Declarations of other (top level) structures have distinct names so it's ok too.
edit
Note that all variables it this header are really marked with
extern
.确实应该有一个
extern
。但是,该变量没有显式定义,因此编译器会为您将其标记为 extern。如果您有...,您将收到链接器错误
,因为每个翻译单元确实定义一次符号(因此链接器会抱怨)。
There should be an
extern
indeed. However, there's no explicit definition of that variable, so the compiler marks it as extern for you.You would get a linker error if you had
...since this does define the symbol once per translation unit (and hence the linker complains).