我是靠谱客的博主 孝顺眼神,最近开发中收集的这篇文章主要介绍【C语言内功心法】__weak -- 示弱也是一种强大,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

大隐隐于市,小隐隐于野,深藏于人海,天下有道则见,无道则隐,君子藏器于身,待时而动。

-- 东方朔 +《周易》+ 《论语》

何为__weak?

__weak 用于修饰函数,赋予这个函数 的属性。

在使用 STM32hal 库的时候,我们常常可以看到很多库自带的函数有很多是使用 __weak 修饰的,比如:

image-20220911131759212

国内的知名操作系统 RT-Thread 也有大量使用 __weak 这个修饰符。

/* Compiler Related Definitions */
#ifdef __CC_ARM                         /* ARM Compiler */
    #define RT_WEAK                     __weak
#elif defined (__IAR_SYSTEMS_ICC__)     /* for IAR Compiler */
    #define RT_WEAK                     __weak
#elif defined (__GNUC__)                /* GNU GCC Compiler */
    #define RT_WEAK                     __attribute__((weak))
#elif defined (__ADSPBLACKFIN__)        /* for VisualDSP++ Compiler */
    #define RT_WEAK                     __attribute__((weak))
#elif defined (_MSC_VER)
    #define RT_WEAK
#elif defined (__TI_COMPILER_VERSION__)
    #define RT_WEAK
#else
    #error not supported tool chain
#endif

首先来看看,先看看单词的意思:

image-20220911111557334

整个单词的释义突出了一个 字,虽然每个人努力修炼,都是为了变得更强,然后偶尔地示弱也是大智慧,那么 weak的弱能够在开发中提供怎样地帮助呢?

弱是相对的

首先 是相对的,具体弱在哪里?又是和什么比较?

其实函数名称前面加上 __weak 修饰符,我们一般称这个函数为“弱函数”

假如工程中存在了一个__weak 修饰符的函数,用户还可以在工程中重新定义一个与之同名的函数,最终编译器编译的时候,会选择没有__weak 修饰符的函数,如果用户没有重新定义新的函数,那么编译器就会执行 __weak 声明的函数,并且编译器不会报错。

既是弱肉强食,弱为何能生存?

一般来说,__weak 修饰符的函数是有软件供应商去定义的(比如 ST 提供的库函数),因为会使用到一些回调函数(比如中断回调函数等),所以需要定义该函数,才能在编译的时候不会报错。但是这些函数一般是开发者要使用,如果直接去软件供应商定义的函数里面实现功能,就会造成文件内容耦合,开发者切换平台或者工程时,做的工作量会更大。

所以软件供应商会用 __weak修饰实现函数,目的是保证编译能够正常通过,开发者要使用的时候,可以在自己的文件中再定义该函数,然后在该函数实现自己的功能,此时编译器会忽略 __weak弱化后的函数。当然如果你稍微懒了点,也可以不定义新的函数,用定义好的__weak修饰的函数实现自己的功能,编译器也照收不误。

还有一种情况是如果拿到的程序库的是软件包的格式(看不到源代码的那种),那你就得自己去定义这个同名函数去实现自己的功能。这个功能用处还挺大,笔者就遇到过要给客户提供功能模块代码,由于不能提供源码,只能提供软件包文件(一般格式为 .lib),但是又需要给客户提供调用的接口函数,我在软件包定义的话,客户用不了(因为看不到源码),我不定义的话,编译会报错,客户会怀疑你的工程是不是有问题。此时 __weak 真是应对这种问题的大救星,谁还能说它弱呢?

值得注意之处

从上文中的 RT-Thread 代码可以看到,__weak在不同平台有不同面孔,有些甚至没有,这是因为__weak函数修饰符并不是 C 标准的里面的东西,这意味着:

  • 并不是所有的编译器都支持__weak这个特性,有些小众的编译器还真就不支持,所以使用前请查询相关编译器是否支持。

  • __weak在所有支持的编译器中面貌长的也一样,详情还是得查询相关编译器。长得不一样对于代码的移植性可是重大的打击,目前比较好的解决办法是:如前面 RT-Thread代码描述那样,用宏定义结合预编译的方式去给不同的 weak定义统一的名字,比如 RT_WEAK。

更多精彩内容,请点击 CSDN 博客地址http://eureka1024.blog.csdn.net/

更多精彩内容,请关注公众号《嵌入式小散修

在这里插入图片描述

最后

以上就是孝顺眼神为你收集整理的【C语言内功心法】__weak -- 示弱也是一种强大的全部内容,希望文章能够帮你解决【C语言内功心法】__weak -- 示弱也是一种强大所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(46)

评论列表共有 0 条评论

立即
投稿
返回
顶部