结构实例(对象)的全局定义

global definition of structure instance(object)

提问人:Muhammad Afaq Younas 提问时间:11/3/2023 最后编辑:LundinMuhammad Afaq Younas 更新时间:11/3/2023 访问量:38

问:

我有一个关于头 .h 文件中结构实例/对象的全局定义以及在多个源文件中使用该实例的问题。

  • 我有 3 个源文件 (.c) 及其文件 (.h)。
  • 在头文件之一中,结构及其对象定义如下:
typedef struct {
    char *my;
    int x;
} main_t;
  
main_t main;

现在,我可以将该头文件包含在其他源文件中并访问同一实例结构主体的成员,因为它是全局的

  • 我已经尝试过并且它有效,但为什么我没有收到多个定义错误?
  • 我没有使用 extern

我问了一个关于在 c 中声明和使用结构的全局对象的问题。

c 结构

评论

0赞 HolyBlackCat 11/3/2023
1. 请不要用 C++ 标记 C 问题。2. 在 C 语言中,没有 .extern
0赞 paddy 11/3/2023
该变量不是共享的全局变量。包含此标头的每个翻译单元都将获得自己唯一的 called 实例。如果您尝试在某个地方,您将收到链接错误,因为链接器不知道该使用哪一个。解决方案是在标头中声明变量,然后在一个转换单元中定义它。mainmain_tmainextern main_t main;extern
1赞 paddy 11/3/2023
旁注:你真的想有一个变量叫吗?这可能会导致需要标准 main 函数的代码出现问题。main
0赞 Support Ukraine 11/3/2023
“我试过了,它的工作......”好吧,你为什么不发布这段代码,这样我们就可以确切地看到你在做什么
0赞 Lundin 11/3/2023
不要在头文件中定义变量。 是一个可怕的变量名称......在编程时,不要只是为了它而做真正奇怪的事情。main

答:

0赞 Eric Postpischil 11/3/2023 #1

我有一个关于头 .h 文件中结构实例/对象的全局定义以及在多个源文件中使用该实例的问题。

main_t main;AT 文件范围不是一个定义。这是一个暂定的定义。(尽管它的名字,暂定定义实际上并不是一个定义,就像工作面试中的潜在雇员实际上不是雇员一样。但是,如果翻译单元包含暂定定义而没有常规定义,则行为就像翻译单元具有初始值设定项等于 0 的标识符定义一样 (C 2018 6.9.2 2)。

然后,效果是所有三个源文件都包含 的定义。C 2018 6.9 5 表示外部定义的“不得超过一个”定义。违反此约束意味着该行为不是由 C 标准定义的。由于行为不是由 C 标准定义的,因此 C 实现可以自由定义(或不定义)行为。在 GCC 版本 10 之前,GCC 中的默认行为是将暂定定义与常规定义区别对待。允许多个暂定定义,并将它们合并为一个定义。除 GCC 之外,某些工具可能仍会使用此行为。main

因此,您观察到的是,使用您正在使用的工具,不同源文件中的多个暂定定义充当单个通用定义。

使用 GCC,可以选择旧行为(合并暂定定义)或使用 选择新行为(将暂定定义视为常规定义)。-fcommon-fno-common

更多信息请见此处

补充

这不是全局定义,因为 C 没有全局命名空间。在全局名称空间中,在程序中的任何位置声明标识符将使其在整个程序中为人所知。在 C 语言中,最大的作用域是文件作用域,其中声明标识符会通过翻译单元的其余部分知道它。要使标识符在程序中的其他位置已知,必须在使用该标识符的每个翻译单元中声明该标识符,并且这些声明必须链接在一起。这是具有外部链接的文件范围,而不是全局范围。