CodeNebula
C++20coreadvanced

[[likely]] and [[unlikely]] Attributes (C++20 Addition)

C++20 · The Big Four · Compiler flag: -std=c++20

Explanation

Hints to the compiler about branch prediction optimization.

Real-World Scenario

Optimize performance in a hot path of a game loop.

Quick Snippet

snippet.cpp
if (condition) [[likely]] {}

Full Example

likely_unlikely.cpp
// CodeNebula - C++20 Example: [[likely]] and [[unlikely]] Attributes
// Compile: g++ -std=c++20 -Wall -Wextra -o example likely_unlikely.cpp

// [[likely]] and [[unlikely]] are branch prediction hints for the compiler.
// They indicate which branch of an if/switch is expected to be taken most
// often, allowing the compiler to optimize code layout accordingly.

#include <iostream>
#include <vector>
#include <random>
#include <chrono>

// Error handling with [[unlikely]] — errors are rare
int safe_divide(int a, int b) {
    if (b == 0) [[unlikely]] {
        std::cout << "  Error: division by zero!\n";
        return 0;
    }
    return a / b;
}

// Cache lookup with [[likely]] — cache hits are common
struct SimpleCache {
    int cached_key = -1;
    int cached_value = 0;

    int lookup(int key) {
        if (key == cached_key) [[likely]] {
            return cached_value;  // cache hit (expected common path)
        } else [[unlikely]] {
            // cache miss — expensive computation
            cached_key = key;
            cached_value = key * key + 1;
            return cached_value;
        }
    }
};

// Switch statement with likely/unlikely branches
const char* classify_http_status(int code) {
    switch (code) {
        case 200: [[likely]]   return "OK";
        case 301:              return "Moved Permanently";
        case 404: [[unlikely]] return "Not Found";
        case 500: [[unlikely]] return "Internal Server Error";
        default:               return "Unknown";
    }
}

// Loop with rare break condition
int find_first_negative(const std::vector<int>& data) {
    for (std::size_t i = 0; i < data.size(); ++i) {
        if (data[i] < 0) [[unlikely]] {
            return static_cast<int>(i);
        }
    }
    return -1;
}

// Validation with [[likely]] success path
bool process_value(int value) {
    if (value >= 0 && value <= 1000) [[likely]] {
        // Normal processing path
        return true;
    } else [[unlikely]] {
        // Out-of-range error path
        std::cout << "  Value " << value << " out of range!\n";
        return false;
    }
}

int main() {
    std::cout << "=== [[likely]] and [[unlikely]] Attributes ===\n\n";

    // Safe divide: normal case and error case
    std::cout << "safe_divide(100, 7) = " << safe_divide(100, 7) << "\n";
    std::cout << "safe_divide(42, 0)  = " << safe_divide(42, 0) << "\n\n";

    // Cache lookups
    SimpleCache cache;
    std::cout << "Cache lookups:\n";
    std::cout << "  lookup(5) = " << cache.lookup(5) << " (miss)\n";
    std::cout << "  lookup(5) = " << cache.lookup(5) << " (hit)\n";
    std::cout << "  lookup(3) = " << cache.lookup(3) << " (miss)\n\n";

    // HTTP status classification
    std::cout << "HTTP status codes:\n";
    int codes[] = {200, 301, 404, 500, 418};
    for (int code : codes) {
        std::cout << "  " << code << " -> " << classify_http_status(code) << "\n";
    }
    std::cout << "\n";

    // Find negative in mostly-positive data
    std::vector<int> data = {5, 10, 20, 30, 40, -3, 60};
    int idx = find_first_negative(data);
    std::cout << "First negative at index: " << idx << "\n\n";

    // Validation
    std::cout << "Validation:\n";
    process_value(42);
    process_value(999);
    process_value(5000);

    return 0;
}

// Expected output:
// === [[likely]] and [[unlikely]] Attributes ===
//
// safe_divide(100, 7) = 14
// safe_divide(42, 0)  =   Error: division by zero!
// 0
//
// Cache lookups:
//   lookup(5) = 26 (miss)
//   lookup(5) = 26 (hit)
//   lookup(3) = 10 (miss)
//
// HTTP status codes:
//   200 -> OK
//   301 -> Moved Permanently
//   404 -> Not Found
//   500 -> Internal Server Error
//   418 -> Unknown
//
// First negative at index: 5
//
// Validation:
//   Value 5000 out of range!
Run command
g++ -std=c++20 -Wall -Wextra -o example likely_unlikely.cpp