10

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

#include <stdio.h>
extern int foo;
int foo = 32;

int main()
{
printf("%d", foo);
}

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

gcc -Wall -Wextra -pedantic foo.c

我没有收到任何警告。

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

4

5 回答 5

14

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

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

于 2013-03-24T13:02:01.873 回答
8

你似乎误解了什么externextern只是让你的声明只是一个声明而不是一个定义。

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

对同一个变量有多个声明是完全正常的,但整个程序中应该只存在一个定义。将此与函数进行比较

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

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

于 2013-03-24T13:01:04.113 回答
7

这似乎很奇怪,因为变量在同一个文件中既定义为外部变量,又定义为全局变量。

extern int foo;

说:它声明时没有定义一个int名为foo.

 int foo = 32;

它声明并定义了一个以外部链接int命名的类型的对象。foo

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

于 2013-03-24T13:01:29.430 回答
2

不同之处在于前者是一个声明 ->extern声明一个变量并说它将在附近的某个地方可用。您可以拥有任意数量的声明,而后者是一个必须恰好存在一次的定义。
所以应该没有警告也没有错误。

于 2013-03-24T13:01:42.180 回答
1

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;
于 2013-03-24T13:07:20.863 回答