weak 顾名思义是“弱”的意思,在汇编中, 在函数名称后面加[WEAK]来表示, 而在 C语言中,在函数名称前面加上__weak 修饰符来表示, 这样的函数我们称为“弱函数”。

被[WEAK]或__weak 声明的函数, 我们可以在自己的文件中重新定义一个同名函数,最终编译器编译的时候,会选择我们定义的函数,如果我们没有重新定义这个函数,那么编译器就会执行[WEAK]或__weak 声明的函数,并且编译器不会报错。

例如,在正点原子战舰开发板 HAL 库例程实验 1 跑马灯实验。我们用 HardFault_Handler中断函数举例。在启动文件的 161 行到 165 行,定义了 HardFault_Handler 中断函数,且声明为“弱函数”,如图

同样我们打开stm32f1xx_it.c文件的60行到66行也定义了HardFault_Handler中断函数,如图

在 stm32f1xx_it.c 文件定义了 HardFault_Handler 中断函数的情况下,当HardFault_Handler 中断来到的时候,代码会运行到 stm32f1xx_it.c 文件的 HardFault_Handler中断函数,且进入 while(1)。
下面,我们注释掉 stm32f1xx_it.c 的 HardFault_Handler 中断函数,然后进行编译,发现不会报错。这时候当 HardFault_Handler 中断来到的时候,代码会运行到启动文件的“弱函数”中,即在启动文件中 164 行代码,进行原地跳转(即无限循环)

需要注意的是在C语言中__weak是一个宏,和__packed是同一种东西都是gcc的扩展属性:

#define __packed __attribute__((packed))
#define __weak __attribute__((weak))

如果这个关键字用在函数定义上面,一般情况下和一般函数没有两样。但是当有一个同名函数但是不带__weak被定义时,所有对这个函数的调用都是指向后者(不带__weak那个), 如果有两个一样的函数都用了__weak,那么真正调用那个,就要看连接器了。

物联沃分享整理
物联沃-IOTWORD物联网 » C语言–weak的作用

发表评论