Table of Contents

assert.h

If you have ever had a function produce a wrong result somewhere deep in a call stack with no indication of where things went wrong, assert.h is what you reach for. It provides the assert macro, which checks a condition at runtime and immediately kills the program with a diagnostic message that tells you exactly which file, which line, and which condition failed.

#include <assert.h>
 
int divide(int a, int b) {
    assert(b != 0);   // if false: prints file, line, expression, then abort()
    return a / b;
}

When the condition is false, you get:

Assertion failed: b != 0, file math.c, line 4

…then abort(). You get a crash at the exact line, not some mysterious wrong value three function calls downstream.

Assertions are stripped out entirely when you compile with -DNDEBUG. The preprocessor removes them completely, so they cost nothing in release builds. Because of this, you must never give an assertion a side effect — assert(read_sensor() > 0) would skip the sensor read in production, which is almost certainly not what you want.

C11 added static_assert, which is evaluated at compile time:

static_assert(sizeof(int) == 4, "int must be 32 bits on this platform");

This fires before a single line of your program runs, at compile time. Useful for catching platform assumption mismatches early.

Practice

// compile: gcc -o div div.c
// run: ./div
// description: assertion fires on bad input; rebuild with -DNDEBUG to strip it
 
#include <assert.h>
#include <stdio.h>
 
int divide(int a, int b) {
    assert(b != 0);
    return a / b;
}
 
int main(void) {
    printf("%d\n", divide(10, 2));   // fine: prints 5
    printf("%d\n", divide(10, 0));   // triggers the assertion
    return 0;
}

Run it and you will see 5 printed, then the assertion fires before the second call returns. Now rebuild with -DNDEBUG:

gcc -DNDEBUG -o div div.c && ./div

The assertion is gone. The divide-by-zero silently produces garbage (or a SIGFPE, depending on the platform). That is the point: assertions are for catching bugs during development, not for validating inputs in production.