【相关推荐】
弱符号是相对于强符号而言的,在定义或者声明变量、函数时,未添加 __attribute__((weak))
标识的就默认为强符号。如下,最普通的函数定义,就是定义了一个强符号 void test_strong_ref(void):
void test_weak_attr(void)
{
printf("this is a strong func\r\n");
}
驱动程序往往需要考虑兼容性,因为要兼任很多厂商的不同型号的设备。若驱动程序中使用强符号定义一些与适配的设备的特性相关的功能,则下次适配其他设备时,该强符号函数可能需要被修改,以兼容新的设备。当适配的设备很多时,频繁地更改驱动代码将破坏驱动的可维护性。
弱符号的出现可以很好地解决该问题。弱符号的对象具有可以被重定义的功能(即可以被重载)。下面通过测试说明弱符号这种可被重载的特性。
在 test_weak_attr.c 程序中定义如下弱函数:
// test_weak_attr.c
#include <stdio.h>
__attribute__((weak)) void test_weak_attr(void)
{
printf("this is a weak func\r\n");
}
在 main.c 中定义如下程序:
// main.c
void test_weak_attr(void)
{
printf("this is a strong func\r\n");
}
void app_main(void)
{
printf("init done\r\n");
test_weak_attr();
}
编译运行该 main.c 程序,得到的结果是什么样子的呢?
this is a strong func
将 main.c 中的 void test_weak_attr(void) 函数注释掉,再重新编译运行程序得到的结果是:
this is a weak func
小结:在使用弱符号函数时,我们可以重新定义一个同名的强符号函数来替代它;若没有重新定义一个强函数来替换它,就使用弱函数的实现。弱函数就好像是一个可以被替换的“默认函数”。
值得一提的是,旧版本的编译器还可以使用如下方式的定义(仅声明无效)将一个对象定义为一个弱对象:
__weak void f(void)
{
//code
}
在 linux 的一些代码中,__weak
其实就是通过 __attribute__((weak))
的重命名,两者等效。