Structures, Unions, Enumerations, and Bit-fields
This domain asks you to predict object layout - padding, alignment, union overlap, bit-field packing - and to know which operations on aggregates are legal in C.
Structures
- Members appear in declaration order with padding inserted to satisfy each member's alignment, so
sizeofmay exceed the sum of the member sizes. offsetof(struct S, m)from<stddef.h>gives a member's byte offset; it is not valid for bit-fields.- Whole-struct assignment copies all members (padding bytes take unspecified values).
==and!=are not defined for structs; compare member by member, or usememcmponly when padding is known to match. - Passing or returning a struct copies it. A struct may contain a pointer to itself but not an instance of itself.
Unions and enumerations
- A union is large enough for its largest member, and all members start at offset 0. Reading a member other than the last one written reinterprets the bytes and is implementation-defined for most type pairs.
- An enumeration declares integer constant expressions of type
int, usable ascaselabels and array bounds; the values must fit inint.
Bit-fields
unsigned int flags : 3;allocates at least three bits. Allocation order and packing are implementation-defined, and the width may not exceed the declared type's width.- You cannot take the address of a bit-field or apply
sizeof/offsetofto one. A zero-width bit-field forces the next member to a new storage unit.
Worked example
struct S { char c; int i; char d; };
On a typical machine with four-byte int alignment: c sits at offset 0, three padding bytes follow, i occupies offsets 4–7, d sits at offset 8, and three tail padding bytes keep the array stride aligned - sizeof(struct S) == 12, not 6. Reordering the members as int i; char c; char d; usually yields 8. Every one of these numbers is implementation-defined.
Traps
- Assuming
sizeof(struct)equals the sum of member sizes, or that layout is portable - never serialize a struct by writing raw bytes across platforms. - Comparing structs with
==(a compile error) or withmemcmpwhen padding bytes differ. - Omitting the
structkeyword (struct S s;, notS s;) unless atypedefwas declared. - A signed bit-field of width 1 can hold only
0and-1. - Relying on the order in which bit-fields are packed.