0

0

C++中的__attribute__((packed))有什么用?(取消编译器自动内存对齐)

冰火之心

冰火之心

发布时间:2026-01-11 15:18:09

|

336人浏览过

|

来源于php中文网

原创

必须在需与硬件寄存器、网络协议包、二进制文件或旧ABI严格对齐时使用__attribute__((packed)),它禁用编译器填充字节,使成员紧密排列,但可能导致未对齐访问异常。

c++中的__attribute__((packed))有什么用?(取消编译器自动内存对齐)

什么时候必须用 __attribute__((packed))

当你需要和硬件寄存器、网络协议包、二进制文件格式或旧有 C 结构体 ABI 严格对齐时,__attribute__((packed)) 才真正必要。比如读写某个 MCU 的外设寄存器结构体,或者解析一段从 socket 直接 recv() 来的 raw packet,编译器默认加的 padding 会导致 offsetof 偏移错乱、memcpy 拷贝越界、甚至触发总线错误。

它到底禁用了什么?

它禁止编译器为结构体成员插入任何填充字节(padding),让每个成员紧挨着前一个成员存放,哪怕类型本身要求对齐(如 uint32_t 要求 4 字节对齐)。后果是:sizeof 变小,但访问可能变慢,某些平台(ARMv7 以下、RISC-V 默认)还可能触发未对齐访问异常。

  • 不加 packed:
    struct foo {
        uint8_t a;
        uint32_t b;
        uint8_t c;
    };
    // sizeof == 12(a:1 + pad:3 + b:4 + c:1 + pad:3)
  • 加 packed:
    struct foo {
        uint8_t a;
        uint32_t b;
        uint8_t c;
    } __attribute__((packed));
    // sizeof == 6(a:1 + b:4 + c:1,无 padding)

常见踩坑点

很多人以为加了 packed 就“安全了”,其实不然:

  • __attribute__((packed)) 是 GCC/Clang 扩展,MSVC 不识别(要用 #pragma pack(1) 替代)
  • 它只作用于直接修饰的结构体/联合体,不会递归影响嵌套结构体——嵌套结构体自己也得显式加 packed
  • 即使结构体 packed,指针解引用仍可能因未对齐触发 SIGBUS(尤其在 ARM Cortex-M3/M4 上运行裸机代码时)
  • 不能用于含虚函数、非 POD 类型的 C++ 类;C++20 起标准明确禁止对 non-standard-layout 类使用此属性

替代方案比盲目 packed 更可靠

多数场景下,比起依赖编译器扩展,更推荐显式控制布局:

GAIPPT
GAIPPT

AI PPT制作和美化神器

下载

立即学习C++免费学习笔记(深入)”;

  • std::memcpy 按字节拷入/出固定 buffer,再用 std::bit_cast(C++20)或 std::memcpy 到目标类型
  • 手动展开字段:把 packet 解析成 std::array<:byte n>,再用 std::spanstd::bit_cast 提取字段
  • 若必须用结构体映射,至少加上静态断言:
    static_assert(sizeof(foo) == 6);
    static_assert(offsetof(foo, b) == 1);
    避免后续修改结构体时 silently 破坏协议

真正难处理的不是 packed 本身,而是跨平台未对齐访问的静默差异——同一段 packed 结构体,在 x86 上跑得好好的,搬到 ARM 上就 crash,这种问题往往要到实机联调才暴露。

相关专题

更多
golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

195

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

187

2025.07.04

css中的padding属性作用
css中的padding属性作用

在CSS中,padding属性用于设置元素的内边距。想了解更多padding的相关内容,可以阅读本专题下面的文章。

129

2023.12.07

Java 桌面应用开发(JavaFX 实战)
Java 桌面应用开发(JavaFX 实战)

本专题系统讲解 Java 在桌面应用开发领域的实战应用,重点围绕 JavaFX 框架,涵盖界面布局、控件使用、事件处理、FXML、样式美化(CSS)、多线程与UI响应优化,以及桌面应用的打包与发布。通过完整示例项目,帮助学习者掌握 使用 Java 构建现代化、跨平台桌面应用程序的核心能力。

0

2026.01.14

php与html混编教程大全
php与html混编教程大全

本专题整合了php和html混编相关教程,阅读专题下面的文章了解更多详细内容。

12

2026.01.13

PHP 高性能
PHP 高性能

本专题整合了PHP高性能相关教程大全,阅读专题下面的文章了解更多详细内容。

22

2026.01.13

MySQL数据库报错常见问题及解决方法大全
MySQL数据库报错常见问题及解决方法大全

本专题整合了MySQL数据库报错常见问题及解决方法,阅读专题下面的文章了解更多详细内容。

18

2026.01.13

PHP 文件上传
PHP 文件上传

本专题整合了PHP实现文件上传相关教程,阅读专题下面的文章了解更多详细内容。

7

2026.01.13

PHP缓存策略教程大全
PHP缓存策略教程大全

本专题整合了PHP缓存相关教程,阅读专题下面的文章了解更多详细内容。

6

2026.01.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
CSS3 教程
CSS3 教程

共18课时 | 4.5万人学习

Sass 教程
Sass 教程

共14课时 | 0.8万人学习

Pandas 教程
Pandas 教程

共15课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号