将定义extern声明的变量在哪里?

时间:2013-12-06 11:33:59

标签: c storage

我知道(我相信)变量声明和定义之间的区别。我只想知道在哪里(在哪个对象中)定义一个变量,该变量是用extern链接(在头文件中)声明的,并且在许多源文件中包含了这个头文件,其中使用了变量。 我提到很少declaration and definition links找不到有关此事的信息。

//globalheader.h//

extern int test_var;

//file1.c//
#include "globalheader.h"

static fn1();
fn1
{
   int a;
   a = test_var;
}

//file2.c//
#include "globalheader.h"

static fn2();
fn2
{
   int b = 1;
   test_var = b;
}

在上面的代码片段中,test_var在globalheader.h中使用外部链接声明,该链接包含在file1.c和file2.c中。否定义了这个test_var但是在哪里使用,那么在哪个(在哪个目标文件中)这个test_var会被分配内存?

4 个答案:

答案 0 :(得分:1)

您的test_var未在任何地方定义,因此它不会存在于任何目标文件中,并且如果您执行链接,则会收到链接器错误,指出test_var丢失。< / p>

你负责在你的一个编译单元中定义它,它将在你决定的任何目标文件中,并由链接器决定任何内存位置。

请注意,如果您使用优化编译此特定代码,编译器可能会发现您的静态函数fn1 / fn2从未被调用,并完全消除它们,在这种情况下,将不会有使用{{1}的代码}。

作为旁注,您可以在多个编译单元中定义一个名为tentative definition的变量。另请参阅How do I use extern to share variables between source files?

答案 1 :(得分:1)

“extern”关键字仅通知编译器内存位置可用于给定变量,因此不要分配新的内存区域。因此,当您编译file1.c和file2.c时,相应的对象代码将不包含内存区域。您还可以注意到目标文件的大小。如果您将任何变量声明为extern,则该变量的对象大小不会增加,并且一旦删除extern并重新编译,则对象大小将增加。 在链接时,链接器将搜索目标文件,其中为给定目标文件中的该变量(在另一个文件中定义为extern)定义了内存区域。 根据您的代码,您没有在任何地方定义变量,因此变量test_var的内存区域未在任何地方分配,因此在链接时链接器将抛出错误“undefined reference test_var”。

答案 2 :(得分:0)

您还没有说过您希望变量存在哪个目标文件,因此链接器应该拒绝链接您的代码。一些旧链接器可能允许这样做,但你可以更明确地定义变量。

答案 3 :(得分:0)

当您将变量声明为extern时,它应该存在于其他文件中。在这种情况下,如果不是这种情况,链接器将给出错误。

C中有一个例外(它不存在于C++中)。如果变量也被赋值,它也将被声明。

如果你写:

 extern int var;

var在其他模块中不存在,它将失败。

如果你写:

 extern int var = 0;

var在其他模块中不存在,它会成功。

显然,变量将驻留在声明它的文件中。