理解 C 中的 extern 关键字

understanding extern keyword in C

这条语句 extern int x=4; 在 C 中是什么意思?是否类似于int x=4;

当我在块(函数)外编译代码 extern int x=4; 时,编译器发出警告,而不是错误。

警告:-

warning: 'x' initialized and declared 'extern' extern int x=3;

同时,当我在块(函数)内编译代码 extern int x=4; 时,编译器会引发错误。

错误:-

error: 'x' has both 'extern' and initializer extern int x=3;

怎么回事,我不是 getting.What 声明 extern int x=4; 到底是什么意思?请理清概念。

提前致谢...

extern 的含义有点复杂,因为 C 是随着时间的推移由不同的人尝试不同的东西开发的,而不是从一开始就知道最终产品应该是什么而设计的。

块内的 extern int x=4; 是错误的原因是它违反了 C 2018 6.7.9 5 中的此规则:

If the declaration of an identifier has block scope, and the identifier has external or internal linkage, the declaration shall have no initializer for the identifier.

我不确定该规则的确切动机是什么。一个动机可能是,“编译器正忙于在这里定义一个函数,同时定义另一个东西对编译器来说是意想不到的、尴尬的或困难的。”我不确定它是否真的很难实现,但对于某些编译器来说可能是个问题,尤其是早期的编译器。

警告的一个原因是我们通常使用 extern 和声明来表示“我们声明这个标识符只是为了告诉你在别处定义的对象。”这是惯例问题,不是规则。1 但是初始化说“我们在这里定义一个对象”。所以这是一个对比,编译器会警告你。但是,这并不是实际的规则违规,因此编译器不会将其报告为错误。

脚注

1有适合这种做法的规则。在文件范围内,int x; 是一个 暂定定义 ,而 extern int x; 是一个不是定义的声明。所以这与实践相符; extern int x; 表示我们只是在声明 x,而 int x; 表示我们可能正在定义它。但是,int x = 4;extern int x = 4;都是定义,不违反任何规则。

直觉上,我喜欢将 extern 视为“在另一个文件中引用一个(全局)对象”。您不能在函数内定义全局对象,因此该概念毫无意义。

extern 变量的初始化是可能的,但不推荐。如果实例化未初始化,并且您有条件地添加一组初始化变量的文件中的一个,以及多个使用它的文件。这可能是个坏主意,但如果您在声明中屏蔽了内存的特殊部分,我可以看到它的用例。另一个用例是它是否可以是另一个文件中的全局变量,但您可能包含也可能不包含该文件。在没有外部声明的情况下,编译器会为你分配内存,并把它当作一个普通的全局变量。

如果您在多个文件中初始化多个值,您几乎肯定会遇到链接器错误。