news 2026/5/12 23:15:58

C语言 弱定义机制 解读

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C语言 弱定义机制 解读

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

目录

一、弱定义的概念

二、弱定义与强定义区别

三、弱定义语法

3.1 使用__attribute__((weak))

3.2 使用#pragma weak

四、链接过程

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

六、典型使用场景

6.1 库的默认实现

6.2 中断处理函数


一、弱定义的概念

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

弱定义特点

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

二、弱定义与强定义区别

特性

强定义

弱定义

符号类型

T (Text), D (Data)

W (Weak)

可覆盖性

不可被覆盖

可被强定义覆盖

多重定义

导致链接错误

允许存在多个定义

内存占用

一定会被编译进最终二进制文件(.elf/.hex)

不一定。若有强定义覆盖,则不会被编译进去

使用场景

普通函数/变量

默认实现、钩子函数等

优先级最高最低
形象比喻正式工临时工/备胎

三、弱定义语法

3.1 使用__attribute__((weak))

// 弱定义一个函数 __attribute__((weak)) void weak_function(void) { printf("这是弱定义函数\n"); } // 弱定义一个变量 __attribute__((weak)) int weak_var = 10;

3.2 使用#pragma weak

#pragma weak funcA void funcA() { // ... 默认行为 }

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

四、链接过程

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

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

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

五、代码示例 — 弱函数的定义与覆盖

1)定义并使用弱函数:

// weak_example.c #include <stdio.h> // 弱定义函数 __attribute__((weak)) void my_function(void) { printf("默认的弱定义函数被调用\n"); } int main(void) { my_function(); // 调用函数 return 0; }

2)编译运行:

$ gcc weak_example.c -o weak_example $ ./weak_example 默认的弱定义函数被调用

3)强定义覆盖:

// strong_override.c #include <stdio.h> // 普通的强定义函数 void my_function(void) { printf("强定义函数覆盖\n"); }

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

$ gcc weak_example.c strong_override.c -o override_example $ ./override_example 强定义函数覆盖

六、典型应用场景

6.1 库的默认实现

在开发库时,可以使用弱定义提供函数的默认实现,允许用户通过提供强定义来覆盖默认行为。

好处:库保持默认行为,用户无需修改库源码即可定制功能。

6.2 中断处理函数

在嵌入式系统中,默认中断处理函数通常定义为弱定义,允许应用程序根据需要提供特定的中断处理实现。

好处:避免未定义中断导致崩溃,且支持用户灵活定制中断处理逻辑。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/12 23:14:16

sgayadgsdvwdc

一、OpenAI 1.OpenAI是什么简单来说&#xff0c;OpenAI 大模型 是由美国人工智能公司 OpenAI 开发的一系列大型语言模型&#xff08;LLMs&#xff09; 。你可以把它们想象成拥有巨大“知识储备”和“学习能力”的超级大脑&#xff0c;它们被训练用来理解和生成人类语言&#xf…

作者头像 李华
网站建设 2026/5/12 23:15:55

5步搞定foo2zjs:Linux打印机驱动配置终极指南

5步搞定foo2zjs&#xff1a;Linux打印机驱动配置终极指南 【免费下载链接】foo2zjs A linux printer driver for QPDL protocol - copy of http://foo2zjs.rkkda.com/ 项目地址: https://gitcode.com/gh_mirrors/fo/foo2zjs 在Linux系统中&#xff0c;打印机驱动配置常常…

作者头像 李华
网站建设 2026/4/9 15:08:04

从零到精通:FanControl风扇控制软件的完全实战指南

从零到精通&#xff1a;FanControl风扇控制软件的完全实战指南 【免费下载链接】FanControl.Releases This is the release repository for Fan Control, a highly customizable fan controlling software for Windows. 项目地址: https://gitcode.com/GitHub_Trending/fa/Fa…

作者头像 李华