为什么工会的规模比预期的要大?

Vit*_*Vit 2 c++ unions bit-fields

#include <iostream>
    typedef union dbits {
        double d;
        struct {
            unsigned int M1: 20;
            unsigned int M2: 20;
            unsigned int M3: 12;
            unsigned int E: 11;
            unsigned int s: 1;
        };
    };
    int main(){
        std::cout << "sizeof(dbits) = " << sizeof(dbits) << '\n';
    }
Run Code Online (Sandbox Code Playgroud)

输出:sizeof(dbits) = 16,但是如果

    typedef union dbits {
        double d;
        struct {
            unsigned int M1: 12;
            unsigned int M2: 20;
            unsigned int M3: 20;
            unsigned int E: 11;
            unsigned int s: 1;
        };
    };
Run Code Online (Sandbox Code Playgroud)

输出:sizeof(dbits) = 8

工会规模为何不断扩大?

在第一个和第二个联合中,结构体中位字段的位数相同,为什么大小不同?

我想这样写:

typedef union dbits {
    double d;
    struct {
        unsigned long long M: 52;
        unsigned int E: 11;
        unsigned int s: 1;
    };
};
Run Code Online (Sandbox Code Playgroud)

但是,sizeof(dbits) = 16,而不是 8,为什么?使用结构中的位字段来解析 double 中的位有多方便?

Gos*_*low 8

位字段的成员不会跨越指定存储类型的边界。所以

        unsigned int M1: 20;
        unsigned int M2: 20;
Run Code Online (Sandbox Code Playgroud)

将是 2,unsigned int每个使用 32 位中的 20 位。

在第二种情况下 12 + 20 == 32 适合单个unsigned int.

至于您的最后一个案例,具有不同存储类型的成员永远不能共享。因此,您将得到一unsigned long long加一,unsigned int而不是您想要的单个无符号长整型。

您应该使用uint64_t这样才能获得准确的位数。unsigned int可以是 16 到 128(或更多)位之间的任何值。

注意:位域是高度实现定义的,这只是它通常工作的常见方式。