在c中全局定义变量的extern

我有以下源代码,我感兴趣。

#include  extern int foo; int foo = 32; int main() { printf("%d", foo); } 

这是一段非常正常的代码,当我编译它时

 gcc -Wall -Wextra -pedantic foo.c 

我没有得到任何警告。

这似乎很奇怪,因为变量既被定义为外部变量又被定义为同一文件中的全局变量。 我很确定链接器很容易在同一个文件中找到外部变量的引用,但它看起来不像编码错误吗? 如果是这样,编译器为什么不警告这个呢?

没有什么奇怪的。 您首先声明了一个变量(您承诺编译器存在它),然后您实际定义了它。 这没有问题。

此外,默认情况下,所有非函数本地且未定义为static变量都是extern

你似乎误解了extern作用。 extern只是使你的声明只是一个声明而不是一个定义。

 int i; //definition of i extern int i; //declaration of i 

具有相同变量的多个声明是完全正常的,但整个程序中只应存在一个定义。 将其与function进行比较

 void f(void); //declaration void f(void) //definition(and redeclaration) { } //definition 

为了使用变量或函数,您只需要它的声明。 它的定义可能出现在程序的任何地方(链接器都会找到它)。 Anywhere可以是同一个文件,另一个文件,甚至是外部库。

它似乎已经过时了,因为变量既被定义为外部变量又被定义为同一文件中的全局变量。

 extern int foo; 

说:它声明没有定义名为foo int类型的对象。

  int foo = 32; 

它声明并定义了一个名为foo int类型的对象,该对象具有外部链接。

没有矛盾,它是有效的C代码。

区别在于前者是一个声明 – > extern声明一个变量,并表示它将在某处可用。 您可以拥有任意数量的声明,后者是一个必须只有一次的定义。
所以应该没有警告,也没有错误。

extern是一种为其他地方定义的变量提供可见性的方法…

extern就像一个承诺……

在example.h中

 extern int g;// promises that this will be in the object code to anything that includes example.h 

例。 C

 int g;