What You'll Learn

    • The 5 most common UB sources
    • How compilers exploit UB for speed
    • Sanitizers to detect UB automatically
    • Safe alternatives for every UB pattern

    Understanding Undefined Behavior

    Undefined Behavior (UB) is the most dangerous concept in C++. When your code triggers UB, the compiler is allowed to do literally anything — crash, produce wrong results, or appear to work perfectly today and fail in production tomorrow. Understanding UB is what separates safe C++ from ticking time bombs.

    The 5 Most Common Sources of UB

    Signed integer overflow, out-of-bounds access, null pointer dereference, reading uninitialized memory, and invalid bit shifts account for the vast majority of UB bugs. Each one has a safe alternative that costs almost nothing at runtime.

    Common Mistake: Testing code and concluding "it works." UB can produce correct results on your machine, with your compiler, today — and fail catastrophically after a compiler update or on a different platform.

    Common UB Sources

    See the 5 most common UB traps and their safe alternatives

    Try it Yourself »
    C++
    #include <iostream>
    #include <vector>
    #include <climits>
    using namespace std;
    
    // Undefined Behavior (UB) means the compiler can do ANYTHING
    // — crash, produce wrong results, or even appear to "work" today
    // and break silently tomorrow.
    
    int main() {
        cout << "=== Common UB Examples (safe demos) ===" << endl;
    
        // 1. Signed integer overflow — UB!
        // int x = INT_MAX;
        // x = x + 1;  // UB — compiler assumes this never happens
        cout << "INT_MAX = " << INT_MAX << endl;
        cout <<
    ...

    How the Compiler Exploits UB

    The compiler assumes your code never has UB. This is how it optimizes: if dereferencing a pointer is UB when null, the compiler assumes the pointer is never null — and can remove your null checks. This makes UB bugs extremely hard to debug because the "safety net" code you wrote gets silently deleted.

    Pro Tip: Compile with -Wall -Wextra -Werror and -fsanitize=undefined in debug builds. UBSan catches most UB at runtime with minimal overhead.

    Compiler UB Exploitation

    See how the compiler assumes and optimizes around UB

    Try it Yourself »
    C++
    #include <iostream>
    #include <cstring>
    using namespace std;
    
    // The compiler EXPLOITS UB for optimization
    // If your code has UB, the optimizer can remove checks,
    // reorder statements, or delete entire branches.
    
    // Example: compiler removes null check because
    // dereferencing null is UB, so pointer "can't" be null
    void demonstrateCompilerAssumptions() {
        cout << "=== Compiler Exploits UB ===" << endl;
    
        // The compiler reasons: if you dereference p,
        // then p cannot be null (otherwis
    ...

    Safe Alternatives — Modern C++ Patterns

    For every UB source, modern C++ provides a safe alternative: std::optional for nullable values, .at() for bounds-checked access, std::span for safe array views, and checked arithmetic for overflow prevention.

    Safe Alternatives

    Replace every UB pattern with a safe modern C++ version

    Try it Yourself »
    C++
    #include <iostream>
    #include <vector>
    #include <optional>
    #include <string>
    #include <span>
    #include <numeric>
    using namespace std;
    
    // Modern C++ provides safe alternatives to every UB source
    
    // Safe division with optional
    optional<double> safeDivide(double a, double b) {
        if (b == 0.0) return nullopt;
        return a / b;
    }
    
    // Bounds-checked array wrapper
    template<typename T, size_t N>
    class SafeArray {
        T data[N]{};
    public:
        T& at(size_t i) {
            if (i >= N) throw out_of_range("In
    ...

    Quick Reference

    UB SourceSafe Alternative
    Signed overflowUnsigned types or checked arithmetic
    Out-of-bounds.at() or std::span
    Null dereferencestd::optional or check first
    Uninitialized readAlways initialize ( or = 0)
    Invalid shiftCheck shift amount < bit width

    Lesson Complete!

    You now understand what undefined behavior is, why it's dangerous, and how to write UB-free C++ code.

    Sign up for free to track which lessons you've completed and get learning reminders.

    Previous

    Cookie & Privacy Settings

    We use cookies to improve your experience, analyze traffic, and show personalized ads. You can manage your preferences below.

    By clicking "Accept All", you consent to our use of cookies for analytics and personalized advertising. You can customize your preferences or reject non-essential cookies.

    Privacy PolicyTerms of Service