Structs & Unions
Course 1 covered scalars, arrays, and the pointers connecting them. Course 2 opens with C's way of grouping several values into one — and, in the same chapter, its way of letting several values share one.
Declaring & Using Structs
typedef
Referring to struct Point everywhere gets verbose fast. typedef gives the type a shorter name — an idiom so common in real C that it's effectively the default style.
Rust never needed this ceremony — a struct's own name is always the type, directly, with no separate aliasing step required.
Structs Are Pure Data
A C struct has no methods attached to it — no impl block equivalent from Rust. Any function operating on a struct is written separately, typically taking a pointer to it as a parameter. Course 2's own Function Pointers chapter (Ch.7) later shows one way C approximates method-like dispatch without a language feature for it at all.
Unions
A union looks like a struct syntactically, but its members share the same memory — only one is genuinely "active" at a time. A union's sizeof equals its largest member's size, not the sum of all members, unlike a struct.
The Danger of Type Punning via Unions
Reading a union member that wasn't the one last written is, in most cases, undefined behavior — the union itself carries no record of which member is currently valid. Compare this directly to Rust's own data-carrying enums (rust1-6): a Rust enum stores a hidden discriminant tracking which variant is actually active, so accessing the wrong one is caught as a compile-time type error through match, not silently allowed at runtime. A C union tracks nothing at all — the programmer is expected to remember.
| Concept | Rust enum | C union |
|---|---|---|
| Tracks which variant/member is active | yes — a hidden discriminant, checked by match | no — nothing tracks it at all |
| Reading the "wrong" one | not possible — match forces handling every case | undefined behavior in most cases |
| Size | largest variant + discriminant tag | exactly the largest member — no tag |
typedef in one statement is extremely common in real C code — expect to see it constantly when reading existing codebases.
Coding Challenges
Define a Point struct with x and y int fields using typedef struct, create an instance with values 5 and 10, and print both fields.
📄 View solutionDefine a union with an int member and a float member. Write 100 into the int member, then print both the int member and the float member. Explain why they don't show a related value.
📄 View solutionExplain how Rust's enum discriminant makes reading the "wrong" variant impossible at compile time, while a C union has no equivalent safeguard at all — and why this makes the union version genuinely undefined behavior rather than just an inconvenience.
📄 View solutionChapter 1 Quick Reference
structgroups multiple values; access members with.typedef struct { ... } Name;— the idiomatic default, avoiding repeatedstructkeywords- C structs carry no methods — functions operating on them are always separate, taking a pointer
unionmembers share memory —sizeofis the largest member's size, not the sum- Reading the wrong union member is undefined behavior — no discriminant tracks which one is active, unlike Rust's enums
- Next chapter: dynamic memory — malloc/calloc/realloc/free, and C's own version of Rust's ownership model