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

关于__packed__修饰的结构体abc_t的sizeof计算结果疑问

为啥用了__attribute__((__packed__))结构体大小还是20字节?

先把你的代码贴出来方便分析:

typedef struct abc { 
    double a; 
    int b; 
    char c; 
    int d; 
}__attribute__((__packed__))abc_t; 

int main() { 
    //To do place code 
    abc_t tmp; 
    printf("The size is %d\n",sizeof(tmp)); 
    return 0; 
}

你计算的8+4+1+4=17字节是理论上packed生效后的大小,但实际得到20字节,最可能的原因是你用的编译器不支持GCC风格的__attribute__((__packed__))属性,比如微软的MSVC编译器:

情况1:使用MSVC编译器

MSVC完全不认识__attribute__((__packed__))这个语法,会直接忽略这个属性,你的结构体就会按照默认的对齐规则来分配内存:

  • double a占8字节(默认对齐到8字节边界)
  • int b占4字节(对齐到4字节边界,接在a后面刚好是8字节位置,没问题)
  • char c占1字节(从12字节位置开始)
  • 为了让后面的int d满足4字节对齐要求,编译器会在c后面填充3字节,把位置拉到16字节
  • int d占4字节(16-19字节)
  • 总大小就是8+4+1+3+4=20字节,和你看到的结果完全一致。

如果是用MSVC,想要禁用填充,得用它自己的语法:#pragma pack(1),比如:

#pragma pack(1)
typedef struct abc { 
    double a; 
    int b; 
    char c; 
    int d; 
} abc_t; 
#pragma pack() // 恢复默认对齐

int main() { 
    abc_t tmp; 
    printf("The size is %zu\n",sizeof(tmp)); // 注意用%zu输出size_t类型
    return 0; 
}

这样编译出来的结构体大小就是17字节了。

情况2:使用GCC/Clang等支持__attribute__((__packed__))的编译器

如果是用GCC或Clang,正常情况下你的代码应该输出17字节。如果还是得到20字节,可能是这几个小问题:

  1. 属性位置写错了:虽然你写的位置是合法的,但有些旧版本的编译器可能要求把__attribute__((__packed__))放在struct关键字后面,比如:
    typedef struct __attribute__((__packed__)) abc { 
        double a; 
        int b; 
        char c; 
        int d; 
    } abc_t;
    
  2. 编译选项影响:比如开启了某些强制对齐的编译选项,或者目标平台有特殊的内存对齐要求(比如某些嵌入式平台不允许非对齐访问,编译器会强制填充)。
  3. printf格式符错误:sizeof返回的是size_t类型,用%d输出在64位系统上可能会有类型不匹配的问题,建议换成%zu,避免输出错误的数值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:08:56