联合中的位字段 - 这有多便携?

时间:2014-01-25 12:59:19

标签: c++ gcc portability unions bit-fields

我得到了一些带有一堆标志的字段,我需要一种快速而肮脏的方法将所有内容设置为零,所以不是盲目地将结构转换为整数,我决定它会更好"更好&# 34;将位字段放在带有实际整数的并集中。

union Flags {
    uint _all;
    struct {
        uint status : 2;
        uint expanded : 1;
        uint draw : 1;
        uint drawChildren : 1;
        uint hidden : 1;
        uint disabled : 1;
        uint used : 1;
        uint deletable : 1;
        uint incomplete : 1;
        uint isStatic : 1;
        uint isConst : 1;
        uint isVolatile : 1;
        uint isInline : 1;
        uint isMutable : 1;
        uint isExtern : 1;
        uint isRegister : 1;
        uint threadLocal : 1;
        uint packed : 1;
        uint dirty : 1;
        uint native : 1;
        uint dynamic : 1; // 22
        uint _padding : 10;
    } flags;
};

我的问题是这是多么便携?我可以期望它可以使用GCC作为编译器在不同平台上移植(主要是对windows,linux,macos,android,ios感兴趣)吗?

或者可能转换为整数并以这种方式设置它并摆脱联盟是要走的路?我一直在阅读比特字段不可移植,但是例如Qt似乎使用它们相当多,它似乎在我列出的平台上统一工作。

最后但并非最不重要的是,即使没有联合,我还能期望位字段是可移植的吗?

编辑:无法添加C作为标记,但我也需要在C中使用它,所以我不能使用std::bitset,我也有一个需要更多的成员不止一点。

编辑2:还要注意,没有任何成员穿过其对齐边界,我认为这应该导致编译器不添加额外的填充。

编辑3:也许我可以使用GCC的__attribute__(packed)来阻止编译器对结构进行修改?

2 个答案:

答案 0 :(得分:2)

位字段根本不可移植。它们之间的填充取决于实现。也许你想要一个std::bitset

答案 1 :(得分:2)

一旦设置了union的一个成员,所有其他成员的值都是未定义的,因此这在技术上不符合标准。如果要将所有内容设置为零,只需使用memset,这完全符合标准,并且通常会被解释为内在函数,并为您提供最大可能的性能。 (而且它更简单。)