Frontend Labs
⋯

4. Operators, control flow, and the details beginners skip

4.1 switch falls through — on purpose, and that's both a feature and a trap

#include <stdio.h>

void describe(int day) {
    switch (day) {
        case 6:
        case 7:
            printf("weekend\n");
            break;
        case 1: case 2: case 3: case 4: case 5:
            printf("weekday\n");
            break;
        default:
            printf("invalid\n");
    }
}

Forgetting a break is one of the most common beginner bugs; -Wextra warns on implicit fall-through unless you mark it intentional (C17: a comment; C23: [[fallthrough]];).

switch (x) {
    case 1:
        do_thing();
        [[fallthrough]];   // C23 attribute — silences the warning, documents intent
    case 2:
        do_other_thing();
        break;
}

4.2 goto — the feature everyone tells you to avoid, that real C code uses constantly

C has no exceptions and no RAII. The idiomatic way to clean up multiple resources on an error path without deeply nested ifs is a single forward goto to a cleanup label — this is the dominant pattern in the Linux kernel, SQLite, and most production C:

int process_file(const char *path) {
    FILE *f = NULL;
    char *buf = NULL;
    int rc = -1;

    f = fopen(path, "r");
    if (!f) goto cleanup;

    buf = malloc(4096);
    if (!buf) goto cleanup;

    if (fread(buf, 1, 4096, f) == 0) goto cleanup;

    rc = 0; // success
cleanup:
    free(buf);
    if (f) fclose(f);
    return rc;
}

This is not the "goto considered harmful" spaghetti Dijkstra warned about — it only ever jumps forward, to one place, and it's the closest thing C has to a finally block. Part IV and VI show this exact pattern throughout real codebases.

4.3 Short-circuit evaluation is a control-flow tool, not just a boolean trick

// Real-world example: guard a dereference
if (ptr != NULL && ptr->value > 0) {  // right side never evaluates if ptr is NULL
    use(ptr);
}

// Common idiom: use || for "do this or bail"
FILE *f = fopen(path, "r");
if (!f) {
    perror("fopen");
    return 1;
}

Generated from real-life-c-guide.md · 8 Oct 2026 16:36