In C, structures (structs) can include other structures and various data types. However, the placement of fields within a structure can affect its size and alignment. The compiler adds extra bytes (padding) to comply with the alignment based on the largest field. This is important for performance and correct operation of the processor.
If a structure contains nested structures, alignment is applied recursively:
#pragma pack in MSVC or the __attribute__((packed)) attribute in GCC/Clang).Example:
#include <stdio.h> struct Inner { char c; int x; }; struct Outer { char a; struct Inner b; short s; }; int main() { printf("sizeof(struct Inner) = %zu\n", sizeof(struct Inner)); printf("sizeof(struct Outer) = %zu\n", sizeof(struct Outer)); return 0; } // sizeof(struct Inner) = 8 (on 64-bit), sizeof(struct Outer) = 16 or 24
Using pack and packed reduces size by ignoring alignment, but this may decrease performance or cause errors on some platforms (ARM, DSP, etc.).
Question: Can you guarantee the same size of the same structure on all platforms?
Answer: No! The C standard does not guarantee the same alignment, byte order (endian), and may "add" padding between fields and at the end of the structure. For binary compatibility of structures, use manual alignment control and always explicitly test sizeof on each target platform.
Example:
struct Data { char c; int x; }; // sizeof(Data) is usually 8 on 64-bit, 5 or 8 on 32-bit
History
When exchanging a structure between a microcontroller (ARM) and a PC through a binary protocol, the data received from ARM did not match expectations on PC — due to different padding and byte order. This led to incorrect parameter decoding, resulting in physical device control errors.
History
In a network protocol, packed structures were added to speed up data transmission, but it was not considered that on a platform without alignment, individual fields did not work (the processor did not support misaligned access). The result: hardware exceptions when working with network packets.
History
The server was working with an external file consisting of structure records. After a compiler update, the size of the structure changed (different alignment). Old data in the file stopped being read correctly, and part of the information became "corrupted."