因为优化等级出现的 莫名其妙的bug

用宏定义的结构体是【全局变量】

全局变量的【初始化值】存在 FLASH 里

但是 -Oz 最小体积优化下,编译器把 "全 0 初始化" 给优化删除了!

所以变量拿到的还是 RAM 上电脏值!**


1. 先看你这句宏

cpp 复制代码
#define LIB_RingBuffer_EXPORT(x,type,num) \
    type x##Buffer[num]; \
    RingBufferPARM x = { \
        x##Buffer, \
        num, \
        sizeof(type), \
        0, \
        0, \
        0, \
        0, \
    };

调用:

cpp 复制代码
LIB_RingBuffer_EXPORT(gUart2_RX_RingBuffer, uint8_t, 64);

展开后 = 全局结构体变量:

cpp 复制代码
uint8_t gUart2_RX_RingBufferBuffer[64];
RingBufferPARM gUart2_RX_RingBuffer = {
    gUart2_RX_RingBufferBuffer,
    64,
    1,
    0,
    0,
    0,
    0,
};

2. 重点来了:编译器 -Oz 做了什么?

** 编译器规则:全局变量如果是【0 + 常量指针】组合

编译器会判定它属于【.bss 段】(需要自动清 0 的段)

但是!

你的结构体里有:指针 + 数字,编译器识别混乱

-Oz 为了减体积,直接【不执行 Flash → RAM 的初始化赋值】!

结果:

cpp 复制代码
msgBuff    = 正常(指针被保留)
maxMsgNum  = 正常
msgSize    = 正常
deIndex    = 随机脏值 ❌
enIndex    = 随机脏值 ❌
deNum      = 随机脏值 ❌
enNum      = 随机脏值 ❌

你写的 {0,0,0,0} 被编译器优化吃了!


3. 为什么 LIB_RingBuffer_Clear() 就一定有效?

因为:

cpp 复制代码
void LIB_RingBuffer_Clear(PRingBufferPARM p)
{
    p->deIndex = 0;
    p->enIndex = 0;
    p->deNum = 0;
    p->enNum = 0;
}

这是运行时指令 !不是初始化,是运行时赋值! 优化器绝对不敢删!

所以:

  • 初始化宏 = 可能被优化
  • 运行时赋值 = 100% 生效

你写的:

复制代码
RingBufferPARM x = {0,0,0,0};

编译器 -Oz 心里想:

"反正都是 0,我不占 Flash 了,省点空间,让它走.bss 吧"

结果:

没给你赋值成功 → 变量还是脏值!

你手动 Clear():

"我就要在运行时赋值 0,你别管为什么" 编译器老老实实执行 → 正常!


✅ 最终结论(100% 正确)

全局结构体的 {0} 初始化,在 -Oz 优化下不可靠!

必须在【运行时】手动调用一次 Clear () 清零!

这就是为什么:

  • 下载运行正常(调试器会强制清 RAM)
  • 断电重启异常(编译器没给你赋值)
  • 手动 Clear 就 100% 正常

一句话收尾:

不是你写错了,是编译器 -Oz 为了省空间,把你的全局变量初始化 "偷" 了! 运行时手动清零 = 100% 可靠,永远解决

相关推荐
Zwawa2 小时前
把按键和 LED 状态显示出来:第一次看见程序到底在干什么
单片机·嵌入式
haliu2 小时前
【FHE】(十一):密文链协议——两条不变式,和 112 与 2100 的分工
嵌入式·fhe·推理引擎·边缘推理·同态加密推理
haliu2 小时前
【FHE】(十):密文里的 attention——没有 max,softmax 怎么办
人工智能·嵌入式·c·fhe·推理引擎·c11·边缘推理·同态加密推理
不悔哥6 天前
开源OV-Watch:怎么做一个智能手表
单片机·开源·嵌入式
优信电子6 天前
AIT1001 非接触式红外测温模块 STM32 驱动开发实战:从引脚到代码全解析
stm32·嵌入式·温度传感器·红外测温·非接触式测温·ait1001
youcans_6 天前
【嵌入式软件AI编程】16. Claude Code 与 VS Code 的协同开发
stm32·mcu·嵌入式·ai编程·claude code
阿钱真强道6 天前
06 嵌入式操作系统 | vim 与软件管理:apt / 源码编译
ubuntu·vim·嵌入式·apt·源码编译
G.E.M.小白6 天前
【IMX6ULL ARM内核启动与时钟系统超详解】PLL/PFD/分频/根时钟配置
嵌入式·arm·时钟·imx6ull
嵌入式阿蔡6 天前
嵌入式DevOps 2026:AI驱动工具链与CI/CD闭环
嵌入式
嵌入式阿蔡6 天前
嵌入式虚拟化2026:Hypervisor从数据中心走进MCU
嵌入式