Why is sizeof () different on a 64-bit processor?

Consider the following example:

#include <stdio.h> #include <inttypes.h> struct A { uint32_t i1; uint32_t i2; uint32_t i3; uint64_t i4; uint32_t i5; uint32_t i6; uint32_t i7; uint64_t i8; uint32_t i9; }; struct B { uint32_t i1; uint32_t i2; uint32_t i3; uint32_t i4; uint32_t i5; uint32_t i6; uint32_t i7; uint64_t i8; uint64_t i9; }; int main() { struct A a; struct B b; printf("sizeof(a) = %u, sizeof(b) = %u\n", sizeof(a), sizeof(b)); return 0; } 

Output:

 $ ./t2 sizeof(a) = 56, sizeof(b) = 48 $ 

Why are they different on a 64-bit machine? The results of the 32-bit platform are the same:

 $ ./t2 sizeof(a) = 44, sizeof(b) = 44 
+4
source share
8 answers

Some diagrams to help you see:

32-bit:

 +----+----+----+----+----+----+----+----+----+----+----+ | i1 | i2 | i3 | i4 | i5 | i6 | i7 | i8 | i9 | Struct A +----+----+----+----+----+----+----+----+----+----+----+ +----+----+----+----+----+----+----+----+----+----+----+ | i1 | i2 | i3 | i4 | i5 | i6 | i7 | i8 | i9 | Struct B +----+----+----+----+----+----+----+----+----+----+----+ 

64-bit:

 +---------+---------+---------+---------+---------+---------+---------+ | i1 | i2 | i3 |~~~~| i4 | i5 | i6 | i7 |~~~~| i8 | i9 |~~~~| Struct A +---------+---------+---------+---------+---------+---------+---------+ +---------+---------+---------+---------+---------+---------+ | i1 | i2 | i3 | i4 | i5 | i6 | i7 |~~~~| i8 | i9 | Struct B +---------+---------+---------+---------+---------+---------+ 
  • + : address boundaries
  • ~ : padding
+21
source

The compiler aligns the elements of the structure along the border (which is different from your compilation attempts).

Add

 #pragma pack (1) 

at the beginning of the source file and try again.

+8
source

Because it is possible. The compiler should not use the same layout between 32 and 64-bit mode. He can insert padding whenever he wants. You should not rely on the exact location of the structure in the first place.

Basically, it can even change the indentation every time you compile. (It is hard to imagine why the compiler would do this, but it did)

+3
source

64-bit integers must be placed on a 64-bit memory boundary. Thus, when creating structure A on a 64-bit machine, the compiler puts a 4-byte fill space after i3 and i7, thereby adding another 8 bytes to it.

+2
source

Due to filling between items.

+1
source

This is caused by structure alignment: struct A has 3 32-bit values, followed by 64-bit. Regardless of the packaging of the first three elements, a 64-bit element will definitely not start between the boundaries (i.e., occupy half of two separate 64-bit values) on a 64-bit basis, therefore there is at least between the 3rd and 4th elements least 32-bit add-on.

+1
source

sizeof (b) is 48 because the last uint32 takes a full 64 bits (because subsequent uint64s are aligned compared to 64-bit blocks. sizeof (a) takes more, because the first 3 unit32s take 2 blocks, the next 3 take 2 blocks and final uint32 accepts a full 64-bit block

0
source

This is due to alignment.

It is possible that 64-bit integers on your platform should be 64 bit compatible.

So, in the mixed structure, you have 3 32-bit integer, after them another 32-bit addition must be inserted in order to correctly combine the 64-bit integer.

The size difference should disappear if you insert even the amount of 32-bit field in front of your 64-bit field.

0
source

Source: https://habr.com/ru/post/1285763/


All Articles