Your code might actually have undefined behavior as you pass a value of type size_t
where printf
expects an int
for %d
. If int
and size_t
have a different representation, as is the case on most 64-bit systems, the code has undefined behavior and the output might be totally meaningless. You should use %zu
or cast the argument as (int)sizeof(a)
.
In your case, the systems reports a structure size of 24 bytes, which is more than the combined sizes of the members because of padding. The C compiler inserts padding bytes between some of the members and possibly at the end of the structure to ensure that each member is stored at a memory address corresponding to its alignment requirements.
Here is how it works:
long e;
is 8 bytes and requires 8 byte alignment. offset is 0
char c;
is 1 byte, no alignment, offset is 8
float f;
is 4 bytes and 4 byte alignment, therefore 3 padding bytes are inserted between c
and f
, offset is 12
char d;
is 1 byte, no alignment, offset is 16
- 7 padding bytes are inserted at the end of the structure to make its length a multiple of the largest alignment, hence 8 bytes.
The total size of the structure is 24 bytes, as reported.
You could reduce the overhead size by changing the order of fields, moving d
before f
or f
before c
.
Here is a modified version:
#include <stdio.h>
struct s1 {
long e; // offset 0, size 8, bytes [0..7]
char c; // offset 8, size 1, byte [8]
// 3 padding bytes [9..11]
float f; // offset 12, size 4, bytes [12..15]
char d; // offset 16, size 1, byte [16]
// 7 padding bytes [17..23]
};
struct s2 {
long e; // offset 0, size 8, bytes [0..7]
float f; // offset 8, size 4, bytes [8..11]
char c; // offset 12, size 1, byte [12]
char d; // offset 13, size 1, byte [13]
// 2 padding bytes [14..15]
};
int main(void) {
struct s1 a;
struct s2 b;
printf("%zu %zu\n", sizeof(a), sizeof(b)); // prints 24 16
return 0;
}
Note however that the size and alignment requirements for standard types short
, int
, long
, float
and double
vary from one architecture to another. Your program and the one above would produce different output on Windows systems.