Get size of anonymous structure inside union

I hope this is not a duplicate question, but I searched in detail and did not find my specific case before.

I have a simple structure that should also have access to a simple byte array

union { struct { unsigned char a; unsigned char b; // ... Some other members ... unsigned char w; }; unsigned char bytes[sizeof( what? )]; } myUnion; 

Please note that the structure is not named and it also does not have its own member name. This means that I can use myUnion.a to access this member, and not myUnion.myStruct.a .

However, without any name, how can I get the size of the structure for myUnion.bytes[] , besides manually calculating it every time I change something?

My current workaround is to use #define to solve the problem of myUnion.myStruct , but this has a negative side effect of myUnion.myStruct my autocomplete in the editor, and also makes it difficult to understand the data structure.

Any ideas?

Note. . This runs on an 8-bit processor. No problem with word alignment, etc. However, any reservations should probably be indicated, so that someone else does not use the proposed solution improperly.

+6
source share
3 answers

Just get rid of the union. You can safely access any structure with the possibility of conversion as a byte array by specifying your address on char* , and casting will not work when undefined behavior is read from an inactive member of the union.

 struct { unsigned char a; unsigned char b; // ... Some other members ... unsigned char w; // array-style access unsigned char& operator[](size_t i) { return reinterpret_cast<unsigned char*>(this)[i]; } } myStruct; 

The reason it is safe to apply this way is because char is a special exception to the strict anti-aliasing restrictions.

For joins, the only special permission you get is access to members that are “standard layout structures that have a common initial sequence” ... and the array, unfortunately, does not meet the criteria for a standard layout structure. ”I would like to so that this rule changes to “standard layout structure or aggregate”, but the current version of the union is unsafe.


In C99, but not in any version of C ++, you can use a flexible member of an array, and you do not need to specify a size at all.

 union { struct { unsigned char a; unsigned char b; // ... Some other members ... unsigned char w; }; unsigned char bytes[]; } myUnion; 

Strike>

+6
source

This will work:

 union { struct { unsigned char a; unsigned char b; // ... Some other members ... unsigned char w; }; unsigned char bytes[1]; } myUnion; 
+1
source

You cannot circumvent a named anonymous structure.

0
source

All Articles