Bit fields in a union - how portable is this?

送分小仙女□ 提交于 2019-12-12 01:11:14

问题


I got a bit field with a bunch of flags, and I need a quick and dirty way to set everything to zero, so instead of blindly casting the struct to an integer, I decided it would be "better" to put the bit fields in a union with an actual integer.

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;
};

My question is how portable is this? Can I expect it to be portable across different platforms (mostly interested in windows, linux, macos, android, ios) using GCC as a compiler?

Or maybe casting to an integer and setting it this way and getting rid of the union is the way to go? I keep reading that bit fields are not portable, and yet for example Qt seems to use them quite a lot and it does seem to work uniformly across the platforms I listed.

Last but not least, even without the union, can I expect the bit fields to be portable?

EDIT: Could not add C as a tag, but I need this to work in C as well, so I can't use std::bitset, also I have a member that takes more than one bit.

EDIT 2: Also note that none of the members crosses its alignment boundary, which I assume should cause the compiler to not add extra padding.

EDIT 3: Maybe I can use GCC's __attribute__(packed) to prevent the compiler from mangling with the structure?


回答1:


Bit fields aren't portable at all. The padding in between them depends on implementation. Maybe you want a std::bitset




回答2:


Once you set one member of a union, the values of all other members are undefined, so this is technically not standards-compliant. If you want to set everything to zero, just use memset, which is entirely standards-compliant and furthermore will generally be interpreted as an intrinsic and give you the maximum possible performance. (And it's simpler.)



来源:https://stackoverflow.com/questions/21350852/bit-fields-in-a-union-how-portable-is-this

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!