1、链接器对全局符号的引用解析过程:当编译器遇到一个不是在当前模块(可重定位目标文件)中定义的符号(变量或函数名)时,会假设该符号是在其他某个模块中定义的,生成一个链接器符号表条目,并把它交给链接器处理。如果链接器在他的任何模块中都找不到这个被引用符号的定义,就输出一条错误信息并终止。
2、对于Linux编译系统,其将函数和已初始化的全局变量作为强符号,未初始化的全局变量是弱符号。然后根据以下规则来选用:
1)不允许有多个同名的强符号
2)如果有一个强符号和多个弱符号同名,那么选择强符号
3)如果有多个弱符号同名,那么从这些弱符号中任意选择一个
例子如下:
在Linux中使用gcc编译器验证:
bar1.c代码如下:
1 int x = 15212;
2
3 void f()
4 {
5 x = 15212;
6 }
fool.c代码如下:
#include <stdio.h>
2
3 void f(void);
4
5 int x = 15213;
6
7 int main()
8 {
9 f();
10 printf("x = %d\n",x);
11
12 return 0;
13 }
编译结果如下:
将bar1.c代码更改如下:
1 int x;
2
3 void f()
4 {
5 x = 15212;
6 }
编译结果如下:
在Linux下使用g++编译器:
bar1.cpp代码和bar1.c一样,fool.cpp代码如下
1 #include <iostream>
2
3 using namespace std;
4
5 void f();
6
7 int x = 15213;
8
9 int main()
10 {
11 f();
12
13 cout << "x = " << x <<endl;
14
15 return 0;
16 }
编译结果如下:
说明上面的规则在g++中不适用。
在windows下使用vs2015编译:
main.c代码如下:
#include <stdio.h>
#include <stdlib.h>
void f();
int x = 15213;
int main(int argc, char* argv[])
{
f();
printf("x = %d \n", x);
system("pause");
return 0;
}
bar.c代码如下:
int x ;
void f()
{
x = 15212;
}
编译结果如下:
改成C++形式,运行会出现重定义的错误。
总结:上面的规则适用windows和Linux下C文件,但无论是windows还是Linux下都不适用于C++文件。