8

When I print the size of a union like this:

union u {
  char c[5];
  int i;
} un;

using this:

int _tmain(int argc, _TCHAR* argv[])
{
    printf("size of union = %d ",sizeof(un));
    return 0;
}

I get an answer of 8 using Visual C++, but I expected 5. Why?

Well, for the same example, i did something like this:

int i1 = 0x98761234;
un.i = i1;
printf("\n un.c[0] = %x ",un.c[0]);
printf("\n un.c[1] = %x ",un.c[1]);
printf("\n un.c[2]= %x ",un.c[2]);
printf("\n un.c[3] = %x ",un.c[3]);
printf("\n un.c[4] = %x ",un.c[4]);
printf("size of union = %d ",sizeof(un));

i got results like

un.c[0] = 34;
un.c[1] = 12;
un.c[2] = 76;
un.c[3] = ffffff98;

why are there 6fs at un.c[3]

timrau
  • 22,578
  • 4
  • 51
  • 64
Saurabh Ghorpade
  • 1,137
  • 5
  • 15
  • 22

5 Answers5

11

The sizeof operator produces the size of a variable or type, including any padding necessary to separate elements in an array of that type such that everything is still correctly aligned. Since your union has an int member, it needs to be 4-byte aligned, so its "natural" size gets rounded upwards to the next multiple of 4 bytes.


The ffffff98 is because you're compiling with signed char. Using %x with an argument that is not unsigned int causes undefined behaviour; what you're seeing is sometimes called sign-extension. The result of your aliasing is 0x98 reinterpreted as char, which is -104. This retains its value on being promoted to int (this is called the default argument promotions), and the int -104 when aliased as unsigned int becomes 0xffffff98.

M.M
  • 138,810
  • 21
  • 208
  • 365
hmakholm left over Monica
  • 23,074
  • 3
  • 51
  • 73
3

The alignment of your union must be the largest alignment of any of its members. This is 4. Therefore, the size of the union must be aligned to that size. It could have been 5 (as c is the largest member of the union), but because the alignment of the union as a whole is 4, the size of the union is padded to 8.

Note that this is just for VC++. The standard does not specifically require it. Though it does allow implementations to pad types as needed, which VC++ does. GCC could do something different, and there could be compile-time switches you could employ to change this behavior.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
2

enter image description hereCompiler adds few bytes for alignment

Tejas Pawar
  • 690
  • 8
  • 16
1

The compiler can add padding wherever it wants to structs, unions, and classes to speed memory accesses. You are seeing the effect of that. For Visual C++, the padding is usually a multiple of the size of the largest member type. In this instance, the largest member is an int, therefore it pads the union with 3 unused bytes to make the total size 8.

Seth Carnegie
  • 73,875
  • 22
  • 181
  • 249
  • Assuming 4-byte integers, the largest member is c, which is 5 bytes. The compiler rounds this up to 8 by adding padding. If the system is using 8-byte integers, then 8 is used for the union size. – Brian Neal Aug 27 '11 at 04:55
  • @Brian I changed my answer shortly before you commented to "largest member type", to more clearly indicate an int. – Seth Carnegie Aug 27 '11 at 04:56
  • 1
    I dunno, I still don't think your answer is clear or correct. You say the largest member is an int, but it isn't. It is an array of 5 chars. Since 5 > 4 it rounds up to the next multiple of the native word size, which makes it 8. – Brian Neal Aug 27 '11 at 17:13
  • Well maybe we are saying the same thing, just slightly differently after all. – Brian Neal Aug 27 '11 at 17:20
  • 1
    @Brian well take this for example: `union { char[9]; double d; };` on MSVC++, the size is 16. When I say "largest member type" I mean the largest type that considers arrays by the elements that are in them. Because `char` is a base type but `char[5]` is kind of a "compound type." – Seth Carnegie Aug 27 '11 at 17:44
  • I see what you're saying but I agree that it's unclear and slightly misleading the way it's phrased – Lightness Races in Orbit Sep 26 '14 at 11:15
0

Thanks for your suggestions. I tried this with a lots of examples and looks that union size is equivalent to (size of max element)+ padding(depending upon the size of highest datatype used).

Saurabh Ghorpade
  • 1,137
  • 5
  • 15
  • 22