UNIX链接器对强符号与弱符号的处理

本文探讨了在编译过程中强符号与弱符号的概念及其如何影响链接器的行为。通过几个具体的示例,展示了当存在多个符号定义时,链接器是如何选择正确的符号,并讨论了这种选择可能带来的意外后果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

      在编译的时候,编译器向汇编器输出每个全局符号,或是强(strong)或者弱(weak),而汇编器把这个信息隐含地编码在可重定位目标文件的符号表里,函数和已初始化的全局变量是强符号,未初始化的全局变量是弱符号。         根据强弱符号的定义,UNIX链接器使用下面的规则来处理多重定义的符号:

            1.  不允许有多个强符号

            2. 如果有一个强符号,多个弱符号,那么会选择强符号

            3. 如果有多个弱符号,那么从这些弱符号中任选一个

以下是几个小例子:

<1>      

int main()                                              int main()                                             

{                                                          {

       return 0;                                               return 0;

}                                                          }


链接器会提示强符号main被重复定义。


<2>   

/* foo2.c */                                               /* bar3 */

#include <stdio.h>                                int x;

void f();                                                 void f()

int x = 123;                                           {

int main()                                                      x = 132;

{                                                            }

    f();

    printf("x = %d\n", x);

    return 0;

}

    在运行时,函数f会将X的值改为132, 这会给main函数的使用者带来不受欢迎的意外!!!注意,链接器通常不会表明它检测到多个X的定义!!!

执行: ./foo

最后会输出132

<3> 如果x是弱定义,也会发生类似2的问题

* foo2.c */                                               /* bar3 */

#include <stdio.h>                                int x;

void f();                                                 void f()

int x ;                                                 {

int main()                                                      x = 132;

{                                                            }

    x = 123;    

    f();

    printf("x = %d\n", x);

    return 0;

}

输出x = 132


所以GCC有 -fno-common这个选项调用链接器,可以在遇到多重定义的全局符号时给出warning

转载于:https://my.oschina.net/u/589963/blog/135601

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值