0

I was going through this question to reaffirm my understanding of structure padding.I have a doubt now. When I do something like this:

#include <stdio.h>

#define ALIGNTHIS 16 //16,Not necessarily

union myunion
{
  struct mystruct
  {
    char a;
    int b;
  } myst;
  char DS4Alignment[ALIGNTHIS];
};

//Main Routine
int main(void)
{
  union myunion WannaPad;

  printf("Union's size: %d\n\
       Struct's size: %d\n", sizeof(WannaPad),
      sizeof(WannaPad.myst));

  return 0;
}

Output:

Union's size: 16
Struct's size: 8

should I not expect the struct to have been padded by 8 bytes? If I explicitly pad eight bytes to the structure, the whole purpose of nesting it inside an union like this is nullified.

I feel that declaring a union containing a struct and a character array the size of the struct ought to be but isn't, makes way for a neater code.

Is there a work-around for making it work as I would like it?

Community
  • 1
  • 1
Adithya
  • 43
  • 6
  • What compiler and which options are used? – Matt Sep 20 '15 at 10:34
  • 3
    The union will be large enough to hold any of the inner types, but the inner types won't be padded to fit the other inner types. – RamblingMad Sep 20 '15 at 11:00
  • 1
    "*[...] the size [of] the struct ought to be [padded]*" Why? For which sense/use? What would be the gain? – alk Sep 20 '15 at 11:02

3 Answers3

2

Think about it logically.

Imagine I had a union with some basic types in it:

union my_union{
    int i;
    long l;
    double d;
    float f;
};

would you expect sizeof(int) == sizeof(double)?

The inner types will always be their size, but the union will always be large enough to hold any of its inner types.

RamblingMad
  • 5,332
  • 2
  • 24
  • 48
  • I wouldn't expect it for primitive data types like the ones you've mentioned. But when you consider a user-defined data-type like struct,a different logic can actually be applied,which seems not to be the case. If I had declared the structure outside and defined an instance of it inside the union I wouldn't have got confused in the first place! Thank you,anyway :-) – Adithya Sep 20 '15 at 17:21
  • @Adithya It makes no difference whether it is a primitive or structure within the union. That was just for illustration of your error in thinking. *any* type will be treated as it would outside of the `union`. No "different logic" can be applied. – RamblingMad Sep 21 '15 at 05:11
1

By default struct is padded, so int b field is aligned on sizeof(int) boundary. There are several workarounds for this:

  • explicitly use fillers where needed: char a; char _a[sizeof(int)-1]; int b;
  • use compiler-dependent pragma to pack struct on byte boundary
  • use command-line switch etc.
Matt
  • 13,674
  • 1
  • 18
  • 27
1

should I not expect the struct to have been padded by 8 bytes?

No, as the struct mystruct is seen/handled on its own. The char had been padded by 3 sizeof (int) -1 bytes to let the int be properly aligned. This does not change, even if someone, somewhere, sometimes decides to use this very struct mystruct inside another type.

alk
  • 69,737
  • 10
  • 105
  • 255