Structures, Unions, Enumerations and typedef
This domain tests user-defined types: grouping related data in a struct, overlapping storage in a union, naming integer constants with enum, and creating aliases with typedef.
Structures
A struct groups named members, each with its own storage: struct point { int x; int y; }; - note the required semicolon. Access a member with . on a value and -> on a pointer. Initialise with struct point p = {1, 2}; and copy with p2 = p1;, which copies member by member. Comparing whole structs with == is not allowed; compare member by member. The compiler may insert padding, so sizeof(struct) can exceed the sum of the member sizes.
Unions and enumerations
A union gives all its members the same storage, and its size is at least that of the largest member; only the member written last is meaningful. enum color { RED, GREEN = 5, BLUE }; defines integer constants - RED is 0, GREEN is 5, BLUE is 6 - which are ordinary int values and cannot be assigned to.
typedef
typedef creates an alias, not a new type: typedef struct point Point; then Point p;. It is common for pointer and function-pointer types, for example typedef int (*cmp)(const void *, const void *);.
Worked example
struct s { char c; int i; };
union u { char c; int i; };
sizeof(union u) is typically 4 - the largest member - while sizeof(struct s) is typically 8 rather than 5, because the int must be aligned on a 4-byte boundary and the struct is padded to a multiple of its alignment.
Traps
- Omitting the semicolon after the closing brace of a struct definition.
- Using
.on a pointer, or->on a plain struct value. - Assuming a union's members hold independent values.
- Expecting
sizeof(struct)to equal the sum of the members. - Treating enum constants as variables.