链接器解析多重定义的全局符号

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++文件。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值