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

为什么包含位域结构体的union实际大小为4字节而非预期的1字节

问题原因及规则说明

1. 位域基类型的默认规则

你遇到的大小异常核心原因是位域的基类型选择:
C语言标准未强制约束位域的基类型大小,主流桌面编译器(MSVC、GCC、Clang等)中,裸写unsigned作为位域类型时,默认指代unsigned int,在32/64位环境下大小为4字节。
即使你在单个结构体里的所有位域总宽度只有8比特,整个结构体的大小也会至少对齐到基类型unsigned int的大小(4字节),因此你定义的三个匿名结构体实际大小都是4字节。

2. #pragma pack(1)的作用边界

#pragma pack(1)仅控制结构体不同成员之间的地址对齐偏移,不会修改位域的基类型大小规则,因此即使加了这句指令,三个匿名结构体的大小依然为4字节,union取内部最大成员的大小,最终结果就是4字节。

3. 赋值不覆盖的原因

你观察到的赋值效果叠加属于正常行为:
前两行STAT.BC9 = 0、STAT.BC8 = 0是修改对应位域的比特位,第三行用的是Val |= byteToSend按位或操作,该操作仅会将byteToSend中为1的比特位置1,不会修改其他比特位,因此会和前两行的修改结果合并,而非覆盖。如果直接写Val = byteToSend才会覆盖整个字节的所有比特位。

4. 调整为1字节union的方案

只要把所有位域的基类型从unsigned替换为1字节的无符号类型(你代码中定义的BYTE类型即可),就能让整个结构体大小压缩为1字节,示例修改如下:

#pragma pack(1)
typedef union _STATUS
{
    BYTE Val;
    struct {
        BYTE BC8 : 1;
        BYTE BC9 : 1;
        BYTE BSTALL : 1;
        BYTE DTSEN : 1; 
        BYTE INCDIS : 1;
        BYTE KEN : 1;   
        BYTE DTS : 1;   
        BYTE UOWN : 1;  
    };
    struct {
        BYTE BC8 : 1;
        BYTE BC9 : 1;
        BYTE PID0 : 1;
        BYTE PID1 : 1;
        BYTE PID2 : 1;
        BYTE PID3 : 1;
        BYTE : 1;
        BYTE UOWN : 1;
    };
    struct {
        BYTE : 2;
        BYTE PID : 4; 
        BYTE : 2;
    };
} STATUS;

修改后sizeof(STATUS)的结果就会是预期的1字节。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 12:48:04