更新时间:2021-09-14 22:43:33
在任何函数之外,int x;
是暂定定义,某些编译器和链接器将其视为一种"协作定义",其中标识符可以以这种方式在多个文件中声明,并将导致仅定义一个对象。
C对外部声明(函数外的声明)的规则由于历史原因有点复杂-C是随着不同的人开发和实验而发展起来的,而不是通过我们今天所拥有的知识进行设计。
定义:函数外部int x = 3;
是一个定义。它既声明标识符x
,又为int
保留内存,并将int
初始化为3。
声明:extern int x;
是声明而不是定义。它声明标识符x
,但不为其保留内存。
这两个声明都提供了x
外部链接。这意味着,当它们出现在不同的源文件中时,标识符的两个实例将链接以引用内存中的同一项内容。
暂定定义:int x;
是混合体。这是一种特殊的可能定义,称为暂定定义。C标准规定,如果翻译单元中存在暂定定义(正在编译的源文件及其包含的所有文件),并且没有常规定义,则暂定定义将成为常规定义。
当程序最多违反关于一个定义的规则时,编译器和链接器中的常见行为是:
这是在GCC版本10之前的GCC和相关工具中定义的默认行为,并在2018年C标准关于通用扩展的信息部分(J.5.11)中明确提到。在当前版本的GCC中,默认情况下,任何类型的多个定义都被视为错误。您可以使用命令行开关-fcommon
请求旧行为。