__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还有一个特性就是强引用和弱引用,我们知道的是,编译器在编译阶段只负责将源文件编译成目标文件(即二进制文件),然后由链接器对所有二进制文件进行链接操作。

在分离式编译中,当编译器检查到当前使用的函数或者变量在本模块中仅有声明而没有定义时,编译器直接使用这个符号,将工作转交给链接器,链接器则负责根据这些信息找到这些函数或者变量的实体地址。

因为在程序执行时,程序必须确切地知道每个函数和全局变量的地址。如果没有找到该符号的实体,就会报undefined reference错误,这种符号之间的引用被称为强引用.

编译器默认所有的变量和函数为强引用,同时编程者可以使用 __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.cnblogs.com/downey-blog/p/10470674.html https://blog.csdn.net/astrotycoon/article/details/8008629

链接:https://xiaoyege.blog.csdn.net/article/details/93674095

仅供大家学习参考与知识传播,版权归原作者所有,如有侵权,麻烦联系进行删除,感谢~

浅谈一下嵌入式中的强符号和弱符号相关推荐

  1. c语言弱符号与函数指针,浅谈C语言中的强符号、弱符号、强引用和弱引用【转】...

    首先我表示很悲剧,在看<程序员的自我修养--链接.装载与库>之前我竟不知道C有强符号.弱符号.强引用和弱引用.在看到3.5.5节弱符号和强符号时,我感觉有些困惑,所以写下此篇,希望能和同样 ...

  2. 嵌入式AI —— 6. 为糖葫芦加糖,浅谈深度学习中的数据增广

    没有读过本系列前几期文章的朋友,需要先回顾下已发表的文章: 开篇大吉 集成AI模块到系统中 模型的部署 CMSIS-NN介绍 从穿糖葫芦到织深度神经网络 又和大家见面了,上次本程序猿介绍了CMSIS- ...

  3. 浅谈单片机程序设计中的“分层思想”!

    浅谈单片机程序设计中的"分层思想",并不是什么神秘的东西,事实上很多做项目的工程师本身自己也会在用.看了不少帖子都发现没有提及这个东西,然而分层结构确是很有用的东西,参透后会有一种 ...

  4. 【嵌入式】C语言高级编程-强符号和弱符号(09)

    00. 目录 文章目录 00. 目录 01. weak属性 02. 变量强符号和弱符号 03. 函数强符号和弱符号 04. 弱符号的作用 05. alias属性 06. 附录 01. weak属性 G ...

  5. 浅谈导航数据中POI搜索技术原理

    浅谈导航数据中POI搜索技术原理之一 王健 导航技术的应用已经成为现在生活中重要组成部分,为我们的生活提供了极大的便利.基本都有这样生活的体验,搜索自己位置附近的银行网点.餐馆.那么这些POI是如何快 ...

  6. 让数据站住脚-浅谈用户研究中的信度与效度

    让数据站住脚-浅谈用户研究中的信度与效度 在用户研究工作中,如何让自己的数据和结论更有说服力,是很重要的问题.最近将自己积累的用研信度和效度的笔记整理一下,罗列在文中,希望对大家有所帮助. 一.调查的 ...

  7. html 怪异模式,CSS_浅谈CSS编程中的怪异模式,怪异模式盒模型 今天学习了 - phpStudy...

    浅谈CSS编程中的怪异模式 怪异模式盒模型 今天学习了一下css3的box-sizing属性,顺便又温习了一下css的盒模型,最后觉得有必要对盒模型做一个全面整理. 先不考虑css3的情况,盒模型一共 ...

  8. 浅谈智能交通中的电子地图

    浅谈智能交通中的电子地图 20世纪80年代以来,随着经济的发展和人口的增长,车和人的矛盾变得越来越尖锐,交通拥挤和阻塞现象日益严重,交通污染与交通事故等日益困扰着交通事业的发展.路网通过能力已不能满足 ...

  9. c语言指针很危险,浅谈C语言中指针使用不当的危险性.doc

    浅谈C语言中指针使用不当的危险性.doc 第 19 卷 Vol . 19 第 2 期 No . 2 洛阳师专学报 Journal of Luoyang Teachers College 2000 年 ...

最新文章

  1. java 读取文件,内容方置Person 并写到另外地址
  2. Java 集合系列(四)—— ListIterator 源码分析
  3. DOM修改元素的方法总结
  4. [云炬创业学笔记]第二章决定成为创业者测试2
  5. HDU 4893 线段树
  6. ubuntu 16.04 kvm 桥接模式创建虚拟机
  7. 痞子衡嵌入式:第一本Git命令教程(0)- 索引
  8. 2018蓝桥杯省赛---java---C---1(哪天返回)
  9. 关于Kafka中的再均衡
  10. Vue中数组变动监听
  11. 自定义Excel导出简易组件
  12. 数据字典中的数据类型与ABAP中的中数据类型对应关系
  13. Android app修改IMEI号
  14. vsftp乱码问题解决
  15. android 自定义动画 相机,Android 自定义view仿微信相机单击拍照长按录视频按钮
  16. docker搭建searx_『颜值即正义』看小睿“自建搜索引擎”
  17. 路由器做二级路由方法
  18. 人人皆可二次元!小姐姐生成不同风格动漫形象,肤色、发型皆可变
  19. c++链表获取长度,链表翻转,查找链表倒数第K个节点以及中间点
  20. elasticsearch查询中文释义、JAVA的API以及kibana上查询

热门文章

  1. 第二节Scala基本类型及操作、程序控制结构
  2. stm32读取编码器的两种方式
  3. pyspark做movielens推荐模型特征工程
  4. png 矢量图 RGBA 转 RGB后变黑问题解决
  5. Could not locate PropertySource: I/O error on GET request for “http://localhost:8888/
  6. masm for Mac|win 环境安装(用masm编写第一条hello world!)
  7. STM32的计数器 例程
  8. 在职高学C语言程序设计,中职学校C语言程序设计教学方法.doc
  9. Java中的public static final来修饰数组与接口变量
  10. vue3+ts实现视频根据时间轴截取