← Advanced C (Pre-Kernel)C PROGRAMMING 1.7.F

C Standards & Undefined Behaviour

C89–C17 differences, _Bool/stdbool, _Static_assert, the real UB inventory (signed overflow, null deref, OOB, strict aliasing, UAF), integer promotions, the -1 < 1U trap.

StatusCollected
NotesChapter test: 2/5 first attempt → retake 4/5 (80%)

Six pieces, and this chapter reframed how I read C in general — a lot of code that looks fine and "just works" is actually relying on behavior the standard never actually promises.

What undefined behavior actually means

It doesn't mean "crashes" — it means the standard places zero requirements on what happens, so the compiler is free to do literally anything, including something that looks completely fine right up until a different compiler flag or a different platform makes it not fine. The real inventory: signed integer overflow, dereferencing NULL, reading or writing out of bounds, violating strict aliasing (accessing memory through an unrelated type), and use-after-free.

_Static_assert(sizeof(int) == 4, "this code assumes a 4-byte int");

_Static_assert catches assumptions like that at compile time instead of leaving them to fail silently at runtime on some other platform.

The signed/unsigned comparison trap

if (-1 < 1U) {
    printf("true\n");
} else {
    printf("false\n");   /* this branch actually runs */
}

This one genuinely surprised me. When a signed int is compared against an unsigned int, the signed value gets implicitly converted to unsigned first — -1 becomes UINT_MAX, which is not less than 1U. The comparison silently does the opposite of what it looks like it should, with no warning at the call site.

Integer promotions

char and short operands get silently promoted to int before almost any arithmetic or comparison — meaning the types actually being compared or added are often not the ones written in the source at all. It's part of why the signed/unsigned trap above needs care: the promotion rules decide which type "wins" before the comparison even happens.

Notes from readers

Comments — via GitHub