You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

嵌入式开发中不遵守内存对齐要求是否属于C语言未定义行为?

问题解答

写入操作的实际结果

首先,你给出的写入地址0x10001为奇数地址,而uint16_t类型的宽度为2字节,对应访问要求2字节对齐(地址最低位为0),这种未对齐访问的结果完全取决于你使用的硬件架构:

  • 8位架构(如AVR8、STC 8051):本身不存在多字节对齐要求,所有16位访问都会默认拆分为两次1字节操作,不会触发异常,普通RAM场景下读写结果都符合预期。
  • 触发硬件异常:ARM Cortex-M0/M0+、老版本MIPS、PowerPC等绝大多数低功耗嵌入式RISC架构不支持未对齐的多字节访问,执行这行代码会直接触发HardFault/总线错误异常,如果没有实现对应异常处理函数,程序会直接跑飞、复位或者进入死循环。
  • 自动拆分访问(无报错但有额外开销):ARM Cortex-M3/M4/M7等支持未对齐访问的架构,硬件会自动把16位写入拆分为两次连续的1字节写入,分别写入0x10001和0x10002地址,不会触发异常,但访问耗时是对齐访问的2~3倍。如果目标地址是外设寄存器,绝大多数外设要求配置寄存器必须单次多字节写入,拆分写入会直接导致外设配置失效、功能异常。

相关运行保证

C语言标准明确规定:对不符合目标类型对齐要求的指针解引用属于未定义行为,没有任何官方运行保证。高优化等级下编译器甚至会直接删除这行未定义的操作代码,不会生成对应的硬件访问指令。
另外如果0x10001是内存映射的外设地址,你没有给指针加volatile修饰,编译器也可能会优化掉这写写入操作,判定后续没有用到该地址的读操作时直接跳过写入。

后续读取操作的结果

读取操作的结果和写入的结果强相关:

  • 如果写入阶段已经触发硬件异常,读取代码根本不会被执行,程序已经停在异常处理流程中。
  • 架构支持未对齐访问且目标地址为普通RAM:硬件会自动拆分两次1字节读取,拼接后的值和你写入的myShort完全一致。
  • 架构支持未对齐访问且目标地址为外设寄存器:两次独立的1字节读取会导致结果不符合预期,很多外设寄存器读一次就会自动清空状态位,第二次读取的是清空后的状态,拼接出来的16位值完全没有参考意义。
  • 没有加volatile修饰的情况下,高优化等级下编译器会直接优化掉真实的硬件读取操作,直接把myShort的值赋值给myShortOrIsIt,哪怕硬件地址的内容已经被外设修改,你也无法拿到最新的硬件值。

内容的提问来源于stack exchange,提问作者Julien BERNARD

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 10:54:01