我有一个关于C链接中符号解析的问题(特别是与elf格式有关)。
假设我将两个模块拆分为单独的文件module1.c和module2.c:
// module1.c
int main() {
return 0;
}
==========================
// module2.c
int main = 3;
int p2() {
return 0;
}
将这两者编译在一起会给我一个链接器错误,因为两个模块中的main都有一个重复的符号。我的问题是,为什么链接器不能解释一个是函数而一个是变量的事实?这些信息肯定存在于两者的符号表中:
Symbol table '.symtab' contains 9 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS a.c
2: 0000000000000000 0 SECTION LOCAL DEFAULT 1
3: 0000000000000000 0 SECTION LOCAL DEFAULT 2
4: 0000000000000000 0 SECTION LOCAL DEFAULT 3
5: 0000000000000000 0 SECTION LOCAL DEFAULT 5
6: 0000000000000000 0 SECTION LOCAL DEFAULT 6
7: 0000000000000000 0 SECTION LOCAL DEFAULT 4
8: 0000000000000000 11 FUNC GLOBAL DEFAULT 1 main
No version information found in this file.
===================================================================
Symbol table '.symtab' contains 10 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS b.c
2: 0000000000000000 0 SECTION LOCAL DEFAULT 1
3: 0000000000000000 0 SECTION LOCAL DEFAULT 2
4: 0000000000000000 0 SECTION LOCAL DEFAULT 3
5: 0000000000000000 0 SECTION LOCAL DEFAULT 5
6: 0000000000000000 0 SECTION LOCAL DEFAULT 6
7: 0000000000000000 0 SECTION LOCAL DEFAULT 4
8: 0000000000000000 4 OBJECT GLOBAL DEFAULT 2 main
9: 0000000000000000 11 FUNC GLOBAL DEFAULT 1 p2
您可以清楚地看到一个是对象,另一个是函数。我的问题是,链接器是否有任何具体原因不旨在对功能和变量进行区分?这是否意味着在由许多模块组成的庞大程序中,您永远不能声明一个与函数同名的全局变量?
答案 0 :(得分:1)
这只是C语言的一个规则:函数和对象没有不同的命名空间。
所以是的 - 你不能拥有一个具有外部链接和相同名称的函数和变量。
请注意,您可以使用static
关键字为文件范围变量和函数提供静态链接,并且在一个文件中具有静态链接的函数和具有静态链接的同名变量是可以的另一个文件。这减少了大型程序发生冲突的可能性。