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

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

            1.  不容许有多个强符号 编码

            2. 若是有一个强符号,多个弱符号,那么会选择强符号 spa

            3. 若是有多个弱符号,那么从这些弱符号中任选一个 编译器

如下是几个小例子: io

<1>       编译

int main()                                              int main()                                              变量

{                                                          { di

       return 0;                                               return 0; 文件

}                                                          } co


连接器会提示强符号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

相关文章
相关标签/搜索