嵌入式C语言的弱符号和弱引用

出处:工程师进阶笔记 发布于:2022-12-23 14:38:28

  __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需要伴随着一个别名才能正常使用
  强/弱符号和强/弱引用的作用
  这种弱符号、弱引用的扩展机制在库的实现中非常有用。
  我们在库中可以使用弱符号和弱引用机制,这样对于一个弱符号函数而言,用户可以自定义扩展功能的函数来覆盖这个弱符号函数。
  同时我们可以将某些扩展功能函数定义为弱引用,当用户需要使用扩展功能时,就对其进行定义,链接到程序当中。
  如果用户不进行定义,则链接也不会报错,这使得库的功能可以很方便地进行裁剪和组合。
  注意:C标准里根本没有提到强、弱符号。这只是GCC这个实现定义的特性,在MS C编译器里是不存在这个概念的。
关键词:嵌入式

版权与免责声明

凡本网注明“出处:维库电子市场网”的所有作品,版权均属于维库电子市场网,转载请必须注明维库电子市场网,https://www.dzsc.com,违反者本网将追究相关法律责任。

本网转载并注明自其它出处的作品,目的在于传递更多信息,并不代表本网赞同其观点或证实其内容的真实性,不承担此类作品侵权行为的直接责任及连带责任。其他媒体、网站或个人从本网转载时,必须保留本网注明的作品出处,并自负版权等法律责任。

如涉及作品内容、版权等问题,请在作品发表之日起一周内与本网联系,否则视为放弃相关权利。

扫码下载APP,
一键连接广大的电子世界。

在线人工客服

买家服务:
卖家服务:

0571-85317607

客服在线时间周一至周五
9:00-17:30

关注官方微信号,
第一时间获取资讯。

建议反馈

联系人:

联系方式:

按住滑块,拖拽到最右边
>>
感谢您向阿库提出的宝贵意见,您的参与是维库提升服务的动力!意见一经采纳,将有感恩红包奉上哦!