Deepak
Deepak

Reputation: 50

OS independent programming of bitfields

I have to program independent bits in a bitfield spanning multiple DWORDS. I am currently using a struct as follows

typedef struct _myStruct
{
    union 
    {
        struct 
        {
            DWORD   field1       : 16
            DWORD   field2       : 8
            DWORD   field3       : 8
        };
        DWORD   value0;
    };
    union 
    {
        struct 
        {
            DWORD   field4       : 32; 
        } 
        DWORD   value1;
    };
} myStruct;

I do this so that a programmer can access independent fields directly, and not remember the corresponding DWORD i.e. as myStruct.field1 etc. This works well in Visual Studio, however GCC complains when I used unnamed structs and unions. To correct that I tried naming the unions and structs as below:

    union _DW0
    {
        struct _BF
        {
            DWORD   field1       : 16
            DWORD   field2       : 8
            DWORD   field3       : 8
        } BF;
        DWORD   value0;
    } DW0;

But now the access is not programmer friendly.. i.e. someone who tries to program this have to remember which DWORD each field belongs to. For eg: myStruct.DW0.field1

Is there a way to get around this?

Upvotes: 1

Views: 342

Answers (2)

Bitfields are inherently non-portable. When you write DWORD field1 : 16; the standard does not determine whether field1 should have the higher or lower 16 bits of the struct. On the other hand, if you use proper types and unions (which in your case suffice, since all your bitfields match a type in most platforms), that can be portable.

Using C++11 types (you can alternatively use a library that has the proper types for your platform):

union {
   struct {
      uint16_t  _1;
      uint8_t   _2;
      uint8_t   _3;
   } field;
   uint32_t value;
};
// ...

Upvotes: 1

bta
bta

Reputation: 45077

Anonymous unions are generally okay, but structures need to have a name. You may be able to use that to cut out one level of 'dot' from your syntax.

However, you're going to have to have slightly-messy syntax if you need to access the fields both individually (as bitfields) and as a whole (as DWORDS) through named structure members. That sort of use case necessitates the union, which necessitates the inner struct, which causes the problem. You can always hide all of the messy syntax behind getter/setter functions but if the structure is large, then that method will not be very maintainable.

Here is an alternative that you can consider:

typedef struct
{
    // DWORD 0
    DWORD   field1   : 16;
    DWORD   field2   : 8;
    DWORD   field3   : 8;
    // DWORD 1
    DWORD   field4   : 32; 
} bitfield_struct;

This only gives you bitfield-level access, but the syntax is cleaner. You can still access the data on the DWORD level if needed, though:

bitfield_struct foo;
DWORD* bar = (DWORD*)&foo;

bar[0] = ...;
bar[1] = ...;

If you typically access your data via bitfield and only rarely access it by DWORD, then this might be an acceptable solution.

Upvotes: 0

Related Questions