嵌入式 C 语言进阶小技巧,弱符号和弱引用_嵌入式 c 语言进阶小技巧,弱符号和弱引用

66 阅读4分钟
         ,赞              17                                   

`__attribute__` 是一个编译器指令,其实是 `GNU C` 的一种机制,本质是一个编译器的指令,在声明的时候可以提供一些属性,在编译阶段起作用,来做多样化的错误检查和高级优化。


用于在 `C`,`C++`,`Objective-C` 中修饰变量、函数、参数、方法、类等。


#### 合理使用 `__attribute__` 有什么好处?


* 给编译器提供上下文,帮助编译器做优化,合理使用可以收到显著的优化效果。
* 编译器会根据 `__attribute__` 产生一些编译警告,使代码更规范。
* 给代码阅读者提供必要的注解,助其理解代码意图。


**总之,\*\*\*\*`__attribute__` 起到了给编译器提供上下文的作用,如果错误的使用 `__attribute__` 指令,因为给编译器提供了错误的上下文,由此引起的错误通常很难被发现。**


### 强符号和弱符号


在同一作用域下不能定义同一个变量或函数,很多C语言学习者都理所当然地这么认为。


这个其实是是有所偏颇的,GNU C对标准C语言进行了扩展,在GCC中,对于符号(在编译时,变量和函数都被抽象成符号)而言,**存在着强符号和弱符号之分**。


是的,是否支持这个特性是由不同的C语言标准决定的。


对于C/C++而言,编译器默认函数和已初始化的全局变量为强符号,而未初始化的全局变量为弱符号。


在编程者没有显示指定时,编译器对强弱符号的定义会有一些默认行为,同时开发者也可以对符号进行指定,使用"**attribute((weak))**"来声明一个符号为弱符号。


定义一个相同的变量,当两者不全是强符号时,gcc在编译时并不会报错,而是遵循一定的规则进行取舍:


* 当两者都为强符号时,重复定义的报错:`redefinition of 'xxx'`
* 当两者为一强一弱时,选取强符号的值
* 当两者同时为弱时,选择其中占用空间较大的符号,这个其实很好理解,编译器不知道编程者的用意,选择占用空间大的符号至少不会造成诸如溢出、越界等严重后果。


在默认的符号类型情况下,强符号和弱符号是可以共存的,类似于这样:



int x; int x = 1;


编译不会报错,在编译时x的取值将会是1.


注意,这里可以使用`__attribute__((weak))`将强符号转换为弱符号,却不能与一个强符号共存,类似于这样:



int attribute((weak)) x = 0; int x = 1;


编译器将报重复定义错误。


### 强引用和弱引用


除了强符号和弱符号的区别之外,GNUC还有一个特性就是强引用和弱引用。


我们知道的是,编译器在编译阶段只负责将源文件编译成目标文件(即二进制文件),然后由链接器对所有二进制文件进行链接操作。


编译器默认所有的变量和函数为强引用,同时编程者可以使用`__attribute__((weakref))`来声明一个函数。


注意这里是声明而不是定义,既然是引用,那么就是使用其他模块中定义的实体,对于函数而言,我们可以使用这样的写法:



attribute((weakref)) void func(void);


,然后在函数中调用`func()`,如果`func()`没有被定义,则`func`的值为0,如果`func`被定义,则调用相应func,在《**程序员的自我修养**》这本书中有介绍,它是这样写的:



attribute((weakref)) void func(void); void main(void) { if(func) {func();} }


但是在现代的编译系统中,这种写法却是错误的,编译虽然通过(有警告信息),但是却不正确:



warning: ‘weakref’ attribute should be accompanied with an ‘alias’ attribute [-Wattributes]


警告显示:weakref需要伴随着一个别名才能正常使用




**收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。**
![img](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/e8127384b7e94749983af5ef0ff51d89~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1772461331&x-signature=tXgO8%2B2RYFOM1DIJDtgpB%2Bz5Qw0%3D)
![img](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/81e06ef6940d48f0bb8e9e1a04e5529e~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1772461331&x-signature=jK99llfBCFUS7Adn4kc0DIVoy14%3D)

**[如果你需要这些资料,可以戳这里获取](https://gitee.com/vip204888)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人**

**都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**