两个相同名称的静态变量(两个不同的文件)和其他任何文件中的外部变量

在一个文件中将变量声明为静态并在另一个文件中执行extern声明 – 我认为这会在链接时出错,因为在任何对象中都不会看到extern变量,因为在其他文件中声明的变量是静态的。 但不知何故,链接器(瑞萨)没有显示任何错误并创建了可执行文件。

如果上面的用例是正确的,如果2个变量在2个不同的文件中声明为静态而另一个在另一个带extern声明的文件中会发生什么? 在这种情况下,将在2个不同的对象中创建2个不同的存储器,但是哪个变量将被链接用于其他变量,在另一个文件中被声明为extern(因为两个变量名都相同)?

在file1.c

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

file2.c中

 static int test_var; fn2() { test_var = 2; } 

file3.c中

 extern int test_var; fn3() { int x; x = test_var; } 

答案可能是您已配置链接器的方式。 如果您正在链接库,那么这里的一切都会正常, file3.o模块将test_var引用为UNDEFINED

如果您正在连接这3个模块的应用程序,那么您将失败,因为缺少main()例程定义和未解析的外部将被视为更不邪恶。 🙂

要检查它,请在构建过程中检查相应的*.o模块符号表,然后检查最终结果。 有这样的方法,你会发现你的奇怪的构建行为的原因。

在您的示例中, file3.c 绝对无法访问file1.cfile2.c变量test_var 。 如果未在file3.c的范围内声明test_var则应该收到链接错误。

在file1.c和file2.c中,关键字static表示变量test_var文件范围 。 这意味着此变量只能在声明它的文件中访问。

在file3.c中,关键字extern表示该变量在其他文件中声明。

当编译器编译file3.c时,它会将变量test_var标记在其他目标文件中,并不关心它在哪里。 因此可以编译此文件,并且不会发生错误。 但是当链接器处理此对象文件时,它会发现没有名为test_var变量可以链接到file3,将显示错误。