Reputation: 50
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
Reputation: 208436
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
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