C语言 弱定义机制 解读

前言 :前面的文章中,我们详细介绍了C++中的纯虚函数,作者联想到C语言中的一个思想与C++的纯虚函数有异曲同工之妙,那就是++弱定义++。弱定义这个概念,可能做嵌入式开发的童鞋接触的会比较多,本文跟大家一起来学习一下。

目录

一、弱定义的概念

二、弱定义与强定义区别

三、弱定义语法

[3.1 使用__attribute__((weak))](#3.1 使用__attribute__((weak)))

[3.2 使用#pragma weak](#pragma weak)

四、链接过程

[五、代码示例 --- 弱函数的定于与覆盖](#五、代码示例 — 弱函数的定于与覆盖)

六、典型使用场景

[6.1 库的默认实现](#6.1 库的默认实现)

[6.2 中断处理函数](#6.2 中断处理函数)


一、弱定义的概念

C语言弱定义是通过特定修饰符声明函数或变量的技术,本质是上是一套链接期 的符号决议规则:同一个全局符号(函数或变量)允许出现多份定义,其中最多只有一份"强定义",其余都是"弱定义"。在链接过程中优先选择强定义的符号,而弱定义仅在没有强定义时被使用。

弱定义特点

  • 允许符号在链接时被覆盖
  • 提供默认实现,可被强定义替换
  • 常用于库函数的可覆盖实现
  • 在gcc中通过 attribute((weak)) 声明
cpp 复制代码
__attribute__((weak))

二、弱定义与强定义区别

特性 强定义 弱定义
符号类型 T (Text), D (Data) W (Weak)
可覆盖性 不可被覆盖 可被强定义覆盖
多重定义 导致链接错误 允许存在多个定义
内存占用 一定会被编译进最终二进制文件(.elf/.hex) 不一定。若有强定义覆盖,则不会被编译进去
使用场景 普通函数/变量 默认实现、钩子函数等
优先级 最高 最低
形象比喻 正式工 临时工/备胎

三、弱定义语法

3.1 使用**attribute((weak))**

cpp 复制代码
// 弱定义一个函数
__attribute__((weak)) void weak_function(void) {
    printf("这是弱定义函数\n");
}

// 弱定义一个变量
__attribute__((weak)) int weak_var = 10;

3.2 使用#pragma weak

cpp 复制代码
#pragma weak funcA
void funcA() { 
   // ... 默认行为
 }

一般普遍使用的是第一种格式。

四、链接过程

链接器在解析符号时遵循以下规则:

  • 如果只有一个强定义,选择该定义
  • 如果有多个强定义,报告多重定义错误
  • 如果有一个弱定义和一个强定义,选择强定义
  • 如果有多个弱定义,任选一个(通常是第一个遇到的)

看到这里,大家有没有觉得弱定义的这种机制,是不是有点像C++中的虚函数/纯虚函数:基类提供"默认实现"的虚函数/纯虚函数,派生类重写来"覆盖"基类的默认行为。(两者的相似性,童鞋们可以细细品味)

五、代码示例 --- 弱函数的定于与覆盖

1)定义并使用弱函数:

cpp 复制代码
// weak_example.c
#include <stdio.h>

// 弱定义函数
__attribute__((weak)) void my_function(void) {
    printf("默认的弱定义函数被调用\n");
}

int main(void) {
    my_function();  // 调用函数
    return 0;
}

2)编译运行:

bash 复制代码
$ gcc weak_example.c -o weak_example
$ ./weak_example
默认的弱定义函数被调用

3)强定义覆盖:

cpp 复制代码
// strong_override.c
#include <stdio.h>

// 普通的强定义函数
void my_function(void) {
    printf("强定义函数覆盖\n");
}

4)编译运行weak_example.cstrong_overrid.c文件:

bash 复制代码
$ gcc weak_example.c strong_override.c -o override_example
$ ./override_example
强定义函数覆盖

六、典型使用场景

6.1 库的默认实现

在开发库时,可以使用弱定义提供函数的默认实现,允许用户通过提供强定义来覆盖默认行为。好处:库保持默认行为,用户无需修改库源码即可定制功能。

6.2 中断处理函数

在嵌入式系统中,默认中断处理函数通常定义为弱定义,允许应用程序根据需要提供特定的中断处理实现。好处:避免未定义中断导致崩溃,且支持用户灵活定制中断处理逻辑。

相关推荐
jojo_zjx1 小时前
GESP 25年12月1级 手机电量显示
c++
jun_bai1 小时前
conda环境配置nnU-Net生物医学图像分割肺动脉静脉血管
开发语言·python
blueSatchel1 小时前
bus_register源码研究
linux·c语言
Hi_kenyon2 小时前
JS中的export关键字
开发语言·javascript·vue.js
少控科技2 小时前
QT高阶日记007
开发语言·qt
把csdn当日记本的菜鸡2 小时前
Java设计模式简单入门
java·开发语言·设计模式
宵时待雨2 小时前
数据结构(初阶)笔记归纳6:双向链表的实现
c语言·开发语言·数据结构·笔记·算法·链表
xixi09242 小时前
selenium——浏览器基础操作(启动/访问/窗口控制)
开发语言·python
FMRbpm2 小时前
树的练习7--------LCR 052.递增顺序搜索树
数据结构·c++·算法·leetcode·深度优先·新手入门