c语言weak void,浅尝辄止5-C语言-weak symbol

如果你是写上层代码的程序员(名叫上上),需要下层程序员(名叫下下)提供一个新的API,为了保证版本库里的代码至少是可编译成功的,上上就不得不等下下把API提交,在下下的库文件和头文件发布到上上要改的工程之后,上上才能提交代码。

今天这个东西就可以让上上谁也不用等,直接提交代码,早早下班。

weak symbol

弱符号,这涉及到编译中符号的概念。在Linux开发环境中,有强符号和弱符号,符号简单来说就是函数、变量的名字,对于全局(非局部、非static)的函数和变量,能不能重名是有一定规矩的,强、弱符号就是针对这些全局函数和变量来说的。

符号类型

对象

函数名,赋初值的全局变量

未初始化的全局变量

当代码中同时存在多个强或弱的全局变量时,要遵守如下规则

强符号只能定义一次,否则编译错误

强弱符号同时存在,以强符号为准

没有强符号,则从多个弱符号中任选一个,用–fno-common编译选项可以在这种情况下打出warning

弱符号的声明

弱符号的声明有两种方式

第一种,用__attribute__((weak))修饰,例如

void __attribute__((weak)) func(void);

extern int __attribute__((weak)) var;

第二种,用#pragma weak标记,例如

#pragma weak func

代码演示

main.c

这个文件中main函数调用了2个声明为弱符号的函数,它们是weak0和weak1

#include void __attribute__((weak)) weak0(void);

void __attribute__((weak)) weak1(void);

int main(int argc, char **argv){

//尝试调用弱符号函数weak0

if (weak0){

weak0();

}

else{

printf("weak0=%p\n", weak0);

}

//尝试调用弱符号函数weak1

if (weak1){

weak1();

}

else{

printf("weak1=%p\n", weak0);

}

return 0;

}

weak.c

这个文件中定义了2个函数(它们还是weak0和weak1),并强制声明为弱符号

#include //标记weak0为弱符号

#pragma weak weak0

//标记weak1为弱符号

void __attribute__((weak)) weak1(void);

static char *label = "weak";

void weak0(void){

printf("[%s]%s is called\n", label, __FUNCTION__);

}

void weak1(void){

printf("[%s]%s is called\n", label, __FUNCTION__);

}

strong.c

这个文件中重复定义(与上面重复)了两个函数,它们又是weak0和weak1

#include //两个函数都[不]声明为弱符号

//#pragma weak weak0

//void __attribute__((weak)) weak1(void);

static char *label = "strong";

void weak0(void){

printf("[%s]%s is called\n", label, __FUNCTION__);

}

void weak1(void){

printf("[%s]%s is called\n", label, __FUNCTION__);

}

编译与输出

编译main.c

当弱符号函数链接不成功,处于未定义状态时,其名字所代表的地址为nil。

#gcc main.c -o test && ./test

weak0=(nil)

weak1=(nil)

编译main.c+weak.c

弱符号链接成功时,可以被正常调用。

#gcc main.c weak.c -o test && ./test

[weak]weak0 is called

[weak]weak1 is called

编译main.c+weak.c+strong.c

当强符号定义出现时,弱符号定义不起作用。

#gcc main.c weak.c strong.c -o test && ./test

[strong]weak0 is called

[strong]weak1 is called

上上如何提前下班呢?

他可以直接将新的API声明为弱符号函数,如果函数名地址非空,则可以调用,否则就维持原始逻辑,完全可能和下下一起下班。

对于全局变量,可以有类似的做法吗?

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值