两个相同名称的静态变量(两个不同的文件)和其他任何文件中的外部变量
在一个文件中将变量声明为静态并在另一个文件中执行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.c
或file2.c
变量test_var
。 如果未在file3.c
的范围内声明test_var
则应该收到链接错误。
在file1.c和file2.c中,关键字static
表示变量test_var
是文件范围 。 这意味着此变量只能在声明它的文件中访问。
在file3.c中,关键字extern
表示该变量在其他文件中声明。
当编译器编译file3.c时,它会将变量test_var
标记在其他目标文件中,并不关心它在哪里。 因此可以编译此文件,并且不会发生错误。 但是当链接器处理此对象文件时,它会发现没有名为test_var
变量可以链接到file3,将显示错误。