0

I know that the size of union in c is the size of the largest member of the union. If I define this union:

union Test1
{
   char C; // 1 byte
   uint32_t uTest; // 4 bytes
};

The size of such union "Test1" is 4 bytes.

However, if i define union Test2

union Test2
{
  char C; // 1 byte
  struct 
  {
    char arr[5]; // 5 bytes    
  }sTest;
  uint32_t uT1; // 4 bytes
  uint32_t uT2; // 4 bytes  
};

here the largest member of union "Test2" is the structure "sTest" which is 5 bytes, then the size of the union "Test2" should be 5 bytes, but the compiler tells that it is 8 bytes !!!

Can someone please explain what the size of union "Test2" should be??

Thanks

halim
  • 386
  • 4
  • 14
  • 2
    Padding in the structure? Have you checked the actual `sizeof` of the structure `sTest`? Also see [Why isn't sizeof for a struct equal to the sum of sizeof of each member?](https://stackoverflow.com/questions/119123/why-isnt-sizeof-for-a-struct-equal-to-the-sum-of-sizeof-of-each-member?noredirect=1&lq=1) – Some programmer dude Jul 20 '20 at 07:42
  • Some compilers have a 'packed' pragma available that eliminates any padding on the target architecture. This would, typically, adversely affect performace since extra boolean operations would be required to access some fields:( – Martin James Jul 20 '20 at 07:46
  • yes thanks. I didn't know about memory alignment. – halim Jul 20 '20 at 07:46
  • 1
    In general, an array of `Test2` must make sure the second and later objects are correctly aligned (according to `_Alignof(union Test2)`, which will probably be `_Alignof(uint32_t)`). This is accomplished by rounding the size of _any_ struct or union up to a multiple of its alignment requirement, by adding padding bytes at the end. – Useless Jul 20 '20 at 07:48
  • It would be useful to show the output of `sizeof u.sTest` (may be 5 or 8 depending on ABI) – M.M Jul 20 '20 at 07:58
  • @M.M: the size of `sTest` will probably be five regardless of the ABI, because that structure of five chars would most likely have a very loose alignment requirement. The alignment requirement on the whole union would more likely be dictated by the alignment requirements of the `uint32_t` members. In other words the padding would be at the end of the union, not at the end of `sTest`. This is of course all subject to implementation-specific details but this is the most likely scenario. – paxdiablo Jul 20 '20 at 09:58
  • @paxdiablo some ABIs align any struct to word boundary, e.g. https://stackoverflow.com/questions/43786747/struct-layout-in-apcs-gnu-abi – M.M Jul 20 '20 at 10:09

2 Answers2

4

I know that the size of union in C is the size of the largest member of the union.

If you know that, then I have some bad news for you :-) It's not necessarily true.

C implementations are allowed to insert padding in between members of structures, and after the final member of both structures and unions, in order to meet alignment requirements. The reason for the latter is to ensure, if you create an array of the union type, all elements of the array will be correctly aligned.

In this case (keeping in mind this is an example, as the sizes and alignment requirements may vary per platform), the most stringent requirement is probably that of uint32_t, in that it will prefer to be on a four-octet boundary.

That, combined with the fact that sTest is five octets in size, means that the structure size will be eight octets, not five.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
0

the size of a union will be a multiple of the largest type in the union. Unless the packed modifier is used. (not really a good idea, unless trying to match some incoming data record

user3629249
  • 16,402
  • 1
  • 16
  • 17