提问人:Muhammad Afaq Younas 提问时间:11/3/2023 最后编辑:LundinMuhammad Afaq Younas 更新时间:11/3/2023 访问量:38
结构实例(对象)的全局定义
global definition of structure instance(object)
问:
我有一个关于头 .h 文件中结构实例/对象的全局定义以及在多个源文件中使用该实例的问题。
- 我有 3 个源文件 (.c) 及其文件 (.h)。
- 在头文件之一中,结构及其对象定义如下:
typedef struct {
char *my;
int x;
} main_t;
main_t main;
现在,我可以将该头文件包含在其他源文件中并访问同一实例结构主体的成员,因为它是全局的
- 我已经尝试过并且它有效,但为什么我没有收到多个定义错误?
- 我没有使用 extern
我问了一个关于在 c 中声明和使用结构的全局对象的问题。
答:
我有一个关于头 .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 语言中,最大的作用域是文件作用域,其中声明标识符会通过翻译单元的其余部分知道它。要使标识符在程序中的其他位置已知,必须在使用该标识符的每个翻译单元中声明该标识符,并且这些声明必须链接在一起。这是具有外部链接的文件范围,而不是全局范围。
评论
extern
main
main_t
main
extern main_t main;
extern
main
main