嵌入式C语言(八)

简介: 嵌入式C语言(八)

继续来看看新的属性:weak

这个符号知道是弱,但是这个是干嘛的呢?我们先来学习一下强符号和弱符号

强符号和弱符号

GNU C通过weak属性声明,**可以将一个强符号转换为弱符号。**使用方法如下。

void __attribute__((weak)) func(void);
int num __attribute__((weak))

一个程序中,无论是变量名,还是函数名,在编译器的眼里,就是一个符号而已。符号可以分为强符号和弱符号。

● 强符号:函数名,初始化的全局变量名。

● 弱符号:未初始化的全局变量名。

在一个工程项目中,对于相同的全局变量名、函数名,我们一般可以归结为下面3种场景。

● 强符号+强符号。

● 强符号+弱符号。

● 弱符号+弱符号。

强符号和弱符号主要用来解决在程序链接过程中,出现多个同名全局变量、同名函数的冲突问题。一般我们遵循下面3个规则。

● 一山不容二虎。

● 强弱可以共处。

● 体积大者胜出。

在一个项目中,不能同时存在两个强符号。如果你在一个多文件的工程中定义两个同名的函数或全局变量,那么链接器在链接时就会报重定义错误。

但是在一个工程中允许强符号和弱符号同时存在,如你可以同时定义一个初始化的全局变量和一个未初始化的全局变量,这种写法在编译时是可以编译通过的。

编译器对于这种同名符号冲突,在做符号决议时,一般会选用强符号,丢掉弱符号。

还有一种情况就是,在一个工程中,当同名的符号都是弱符号时,那么编译器该选择哪个呢?谁的体积大,即谁在内存中的存储空间大,就选谁。

不建议在一个工程中定义多个不同类型的同名弱符号,编译的时候可能会出现各种各样的问题。

在一个工程中,也不能同时定义两个同名的强符号,否则就会报重定义错误。

可以使用GNU C扩展的weak属性,将一个强符号转换为弱符号。

链接器对于同名函数冲突,同样遵循相同的规则。函数名本身就是一个强符号,在一个工程中定义两个同名的函数,编译时肯定会报重定义错误。

那弱符号能干嘛呢?

在一个源文件中引用一个变量或函数,当编译器只看到其声明,而没有看到其定义时,编译器一般编译不会报错:编译器会认为这个符号可能在其他文件中定义。

在链接阶段,链接器会到其他文件中找这些符号的定义,若未找到,则报未定义错误。

当函数被声明为一个弱符号时,会有一个奇特的地方:当链接器找不到这个函数的定义时,也不会报错。编译器会将这个函数名,即弱符号,设置为0或一个特殊的值。只有当程序运行时,调用到这个函数,跳转到零地址或一个特殊的地址才会报错,产生一个内存错误。

为了防止函数运行出错,我们可以在运行这个函数之前,先进行判断,看这个函数名的地址是不是0,然后决定是否调用和运行,这样就可以避免段错误了。

弱符号的这个特性,在库函数中应用得很广泛。如你在开发一个库时,基础功能已经实现,有些高级功能还没实现,那么你可以将这些函数通过weak属性声明转换为一个弱符号。通过这样设置,即使还没有定义函数,我们在应用程序中只要在调用之前做一个非零的判断就可以了,并不影响程序的正常运行。等以后发布新的库版本,实现了这些高级功能,应用程序也不需要进行任何修改,直接运行就可以调用这些高级功能。

(我还没做好,低调点,等我做好了就理直气壮了)

还有个alias

这个属性很简单,主要用来给函数定义一个别名。

在Linux内核中,你会发现alias有时会和weak属性一起使用。如有些函数随着内核版本升级,函数接口发生了变化,我们可以通过alias属性对这个旧的接口名字进行封装,重新起一个接口名字。

这不是就不用修改函数了,如果我们在main.c中新定义了f()函数,那么当main()函数调用f()函数时,会直接调用main.c中新定义的函数;当f()函数没有被定义时,则调用__f()函数。

这些逻辑还是有点意思

  • 资料:《嵌入式C语言自我修养》
目录
相关文章
|
3月前
|
机器学习/深度学习 算法 数据挖掘
C语言在机器学习中的应用及其重要性。C语言以其高效性、灵活性和可移植性,适合开发高性能的机器学习算法,尤其在底层算法实现、嵌入式系统和高性能计算中表现突出
本文探讨了C语言在机器学习中的应用及其重要性。C语言以其高效性、灵活性和可移植性,适合开发高性能的机器学习算法,尤其在底层算法实现、嵌入式系统和高性能计算中表现突出。文章还介绍了C语言在知名机器学习库中的作用,以及与Python等语言结合使用的案例,展望了其未来发展的挑战与机遇。
77 1
|
3月前
|
人工智能 安全 算法
基于C语言的嵌入式系统开发,涵盖嵌入式系统概述、C语言的优势、开发流程、关键技术、应用实例及面临的挑战与未来趋势。
本文深入探讨了基于C语言的嵌入式系统开发,涵盖嵌入式系统概述、C语言的优势、开发流程、关键技术、应用实例及面临的挑战与未来趋势。C语言因其高效、可移植、灵活及成熟度高等特点,在嵌入式系统开发中占据重要地位。文章还介绍了从系统需求分析到部署维护的完整开发流程,以及中断处理、内存管理等关键技术,并展望了嵌入式系统在物联网和人工智能领域的未来发展。
149 1
|
8月前
|
C语言
C语言实现2048小游戏---粤嵌GE6818嵌入式系统实训
C语言实现2048小游戏---粤嵌GE6818嵌入式系统实训
|
8月前
|
安全 Unix Linux
嵌入式C语言(十四)
嵌入式C语言(十四)
53 0
|
6月前
|
算法 IDE 程序员
C语言与嵌入式系统:嵌入式C编程基础。
C语言与嵌入式系统:嵌入式C编程基础。
114 0
|
8月前
|
存储 移动开发 C语言
技术心得记录:嵌入式开发中常用到的C语言库函数
技术心得记录:嵌入式开发中常用到的C语言库函数
84 1
|
8月前
|
C语言
C语言实现电子音乐相册---粤嵌GEC6818嵌入式系统实训
C语言实现电子音乐相册---粤嵌GEC6818嵌入式系统实训
|
8月前
|
安全 Linux 编译器
嵌入式C语言(十二)
嵌入式C语言(十二)
47 1
|
8月前
|
存储 算法 Linux
嵌入式C语言(十三)
嵌入式C语言(十三)
43 0
|
9月前
|
数据处理 调度 C语言
C语言:嵌入式硬件利器
C语言:嵌入式硬件利器

热门文章

最新文章