gcc attribute weak & alias应用


1          gcc attribute weak & alias应用

alias ("target")

The alias attribute causesthe declaration to be emitted as an alias for another symbol, which must bespecified. For instance,

         void __f () { /* Do something. */; }

         void f () __attribute__ ((weak, alias ("__f")));

defines ‘f’ to be a weakalias for ‘__f’. In C++, the mangled name for the target must be used. It is an error if‘__f’ is not definedin the same translation unit.

Not all targetmachines support this attribute. 

这段来自GCC官方文档的说明,其实讲了gcc的alias和weak attribute。

1.1        gcc weak attribute

具体语法,大概和一般gcc属性一样,需要用到__attribtes__((weak))这样的格式。现在我们通过一个例子来说明一下。

1 我们在weak_symbol.c这个文件中声明了一个common_print函数,并且将此函数声明为__attribute__((weak));同时提供了此函数的定义。

[cpp]  view plain  copy
  1. //weak_symbol.c  
  2. #include<stdio.h>   
  3. voidcommon_print(const char *s) __attribute__((weak));//有weak声明  
  4. voidcommon_print(const char *s)  
  5. {  
  6.     printf("common_print : %s\n",s);  
  7. }  

2 在strong_symbol.c这个文件也定义了common_print函数,需要注意的是此函数在两个不同的c文件中声明、定义的原型都一样的。

[cpp]  view plain  copy
  1. //strong_symbol.c  
  2. #include<stdio.h>  
  3.    
  4. voidcommon_print(const char *s) //没有weak声明  
  5. {  
  6.     printf("application common_print : %s\n",s);  
  7. }    
  8. int main(intargc, char *argv[])  
  9. {  
  10.     common_print("I want to test gcc weakattribute");  
  11.     return 0;  
  12. }  

3 编译连接连个c文件,并且执行的结果如下:

root@VM-Ubuntu203001:/home/test/gcc_test#./test_weak

applicationcommon_print : I want to test gcc weak attribute

 

分析:

1)      首先,同样的原型的两个函数在连个不同的c文件中都有定义,把这两个c文件编译、连接在一起,也没有什么错误。原因就是因为,gcc中有一个strong symbol和weak symbol的概念。默认函数定义都是strong symbol的,两个相同的strong symbol连接在一起,肯定会产生”symbol重复定义”的错误。

但是,这里我们将weak_symbol.c中的common_print加了weak属性,这样gcc再选择的时候优先选择strong symbol

2)      其次,根据例子程序执行的结果来看,执行了strong_symbol.c中的common_print函数。如果我们在strong_symbol.c中不提供common_print函数的实现,那么调用的就是weak_symbol.c中的实现。

3)      由上,我们可以想象,当要用c语音提供一个api库的时候,我们可以把这些api都声明为weak属性的,我们可以提供default实现。当用户想要自己定制的时候,也就很容易实现了。glibc中的很多api就是这样设计的。

1.2        gcc weak &alias attribute配合应用的场景

同样,先看一个例子。

1 我们在weak_symbol.c中提供了一个__lib_print函数的实现,同时声明了print_aprint_b两个函数,但是和上面不通的是,这两个函数增加了__attribute__((weak,alias("__lib_print")))熟悉,即print_aprint_b都是__lib_print的别名(alias)。

[cpp]  view plain  copy
  1. //weak_symbol.c  
  2. #include <stdio.h>  
  3.    
  4. void __lib_print(const char *s)  
  5. {  
  6.    printf("__lib_print : %s\n", s);  
  7. }  
  8.    
  9. void print_a(const char *s) __attribute__((weak, alias("__lib_print")));  
  10. void print_b(const char *s) __attribute__((weak, alias("__lib_print")));  
2 我们在strong_symbol.c中为 print_b 重新提供了实现, print_a 保持默认不变。

[cpp]  view plain  copy
  1. //strong_symbol.c  
  2. #include <stdio.h>  
  3.    
  4. void print_b(const char *s)  
  5. {  
  6.    printf("application print_b : %s\n", s);  
  7. }  
  8. int main(int argc, char *argv[])  
  9. {  
  10.    print_a("I want to test weak&&alias");  
  11.    print_b("I want to test weak&&alias");  
  12.    
  13.    return 0;  
  14. }  
3  编译连接连个c文件,并且执行的结果如下:

root@VM-Ubuntu203001:/hometest/gcc_test#./test_weak

__lib_print : I want to testweak&&alias

application print_b : I want to testweak&&alias

分析:

   从执行结果来看,print_a执行的是weak_symbol.c中的__lib_print的实现。print_b执行的是strong_symbol.c中的print_b实现。这个执行结果,我们是应该猜到的,需要说明一点是alias属性可以为一个函数提供很多不同的别名。这样,当我们提供api库的时候,如果多个api有相同的default实现,就可以通过alias机制提供一个default 实现。

http://blog.csdn.net/hengshan/article/details/38725971

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值