强弱符号与强弱引用

强弱符号与强弱引

概念

就C/C++而言:

  • 强符号(Strong Symbol):已初始化的全局变量。
  • 弱符号(Weak symbol): 未初始化的全局变量。
  • 强引用(Strong Reference): 如果未找某个符号定义,链接器会报符号未定义错误,这种引用称为强引用。
  • 弱引用(Weak Reference):相对于强引用而言,如果弱引用在链接时可以找到定义,则链接器会将该引用决议(即符号对应到相应的虚地址上);未找到某个符号的定义,链接器也不会报错。

如何定义

在GCC中:

  • 强符号:定义全局变量并将其初始化。如:

      int strongSymbol = 1;
      int main() {
          return 0;
       }
    
  • 弱符号:有两种方式:

      int weakSymbol; //方式一: 定义未初始化全局变量
      __attribute__(weak) weakSymbol2 = 2; //利用GCC扩展属性weak。
      int main() {
          return 0;
      }
    
  • 强引用: 我普通情况下对符号的引用都是强引用。如:

     void foo();     //在别的模块定义
        int main() {
         foo(); //强引用,在链接阶段,链接器必须看到它的定义,否则会报错。
         return 0;
     } 
    
  • 弱引用:弱引用通过扩展关键字__attribute__((weakref)),如:

     __attribute__ ((weakref)) void foo(); //在别的模块定义
        int main() {
        /* 弱引用,在链接阶段,链接器即使找不到它的定义,也会不会报错。
        * 会延迟到程序运行时再决议,如果运行时还是找不到定义,因foo的地址为0,就会发生错误,
        *  可以通过条件判断 if(foo)foo; 防止运行时错误的发生。*/
         foo(); 
         return 0;
     }
    

规则

  • 强符号不可定义多次。否则链接器会抱怨重复定义。但是可以只定义一个强符号,同时存在多个弱符号,链接时链接器会自动选择强符号。
  • 如果没有定义强符号,但是定义了多个弱符号,那么会选择占用空间最大的。

应用场景

  • 强符号和强引用就是我们平常编码最常使用的方式,就不必多说了。
  • 弱符号的应用场景主要在库上,如库可以定义一个备选弱符号,如果用户程序有自定义强符号,就可以覆盖库中定义弱符号,没有的话就可以使用库中弱符号。
  • 弱引用也主要是应用在库中,以在某种程度上实现程序的动态伸缩。如程序将某些扩展功能定义成弱引用,当库与程序链接在一起后,如果弱符号有被定义,则就可以被程序调用;如果去掉某些包含弱引用功能的模块程序也可以正常运行。

参考

  • 程序员的自我修改 --- 链接、装载与库,第三章第五节。

你可能感兴趣的:(强弱符号与强弱引用)