[2026] C++20 consteval Complete Guide | Immediate Functions and Compile-Time-Only Evaluation

[2026] C++20 consteval Complete Guide | Immediate Functions and Compile-Time-Only Evaluation

이 글의 핵심

Master C++20 consteval: immediate functions for compile-time-only evaluation, validation, hashing, and zero-overhead configuration.

Why consteval Exists

Problem: constexpr Ambiguity

Problem: constexpr functions can execute at compile time or runtime. When you want to enforce compile-time computation, it’s ambiguous. 아래 코드는 cpp를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

// 실행 예제
constexpr int factorial(int n) {
    return n <= 1 ? 1 : n * factorial(n - 1);
}
int main() {
    constexpr int x = factorial(5);  // Compile-time: 120
    
    int n = 10;
    int y = factorial(n);  // Runtime (may not be intended)
}

Solution: consteval is compile-time-only. Passing runtime values causes compile error, guaranteeing compile-time computation. 아래 코드는 cpp를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

// 실행 예제
consteval int factorial(int n) {
    return n <= 1 ? 1 : n * factorial(n - 1);
}
int main() {
    constexpr int x = factorial(5);  // OK: 120
    
    int n = 10;
    // int y = factorial(n);  // Error: n is runtime value
}

아래 코드는 mermaid를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

flowchart TD
    subgraph constexpr[constexpr]
        ce1["Compile-time OK"]
        ce2["Runtime OK"]
    end
    subgraph consteval[consteval]
        cv1["Compile-time OK"]
        cv2["Runtime Error"]
    end

Table of Contents

  1. constexpr vs consteval
  2. Immediate Functions
  3. Practical Use: Compile-Time Validation
  4. Metaprogramming
  5. Common Errors and Solutions
  6. Production Patterns
  7. Complete Example: Compile-Time Config System

1. constexpr vs consteval

Comparison

Aspectconstexprconsteval
Compile-time executionPossibleRequired
Runtime executionPossibleNot allowed
PurposeFlexible computationCompile-time guarantee
Error on runtime valueNoYes

Example

다음은 cpp를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

// constexpr: both allowed
constexpr int add(int a, int b) {
    return a + b;
}
int main() {
    constexpr int x = add(1, 2);  // Compile-time
    
    int a = 5;
    int y = add(a, 10);  // Runtime (OK)
}
// consteval: compile-time only
consteval int multiply(int a, int b) {
    return a * b;
}
int main() {
    constexpr int x = multiply(2, 3);  // OK
    
    int a = 5;
    // int y = multiply(a, 10);  // Error: a is runtime value
}

Key: consteval enforces compile-time-only execution.

2. Immediate Functions

What are Immediate Functions?

consteval functions are immediate functions that must be immediately evaluated at call site. 다음은 cpp를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

consteval int square(int x) {
    return x * x;
}
// consteval functions can only be called from consteval
consteval int sum_of_squares(int a, int b) {
    return square(a) + square(b);  // OK
}
// Cannot call from constexpr (if it might run at runtime)
constexpr int wrapper(int x) {
    // return square(x);  // Error: consteval in constexpr
    return x * 2;
}
int main() {
    constexpr int result = sum_of_squares(3, 4);  // 25
}

Output:

25

Key: consteval functions can only be called from other consteval functions or constant expressions.

3. Practical Use: Compile-Time Validation

Range Validation

아래 코드는 cpp를 사용한 구현 예제입니다. 에러 처리를 통해 안정성을 확보합니다, 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

consteval int check_range(int value, int min, int max) {
    if (value < min || value > max) {
        throw "Value out of range";
    }
    return value;
}
int main() {
    constexpr int size = check_range(100, 1, 1024);  // OK
    int buffer[size];
    
    // constexpr int bad = check_range(2000, 1, 1024);  // Compile error
}

Key: Compile-time validation prevents invalid configurations from compiling.

String Hashing

다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고, 반복문으로 데이터를 처리합니다, 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <string_view>
consteval unsigned int hash(std::string_view str) {
    unsigned int hash = 5381;
    for (char c : str) {
        hash = ((hash << 5) + hash) + static_cast<unsigned char>(c);
    }
    return hash;
}
enum class MessageType : unsigned int {
    Login = hash("login"),
    Logout = hash("logout"),
    Data = hash("data")
};
void handle_message(const std::string& type) {
    switch (hash(type.c_str())) {  // Compile-time hash
    case hash("login"):
        std::cout << "Login\n";
        break;
    case hash("logout"):
        std::cout << "Logout\n";
        break;
    case hash("data"):
        std::cout << "Data\n";
        break;
    }
}

Key: Compile-time string hashing enables fast string-based switch statements.

Type Size Validation

다음은 cpp를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

template<typename T>
consteval bool is_small_type() {
    return sizeof(T) <= 16;
}
template<typename T>
    requires is_small_type<T>()
void process(T value) {
    // T guaranteed to be 16 bytes or less
}
int main() {
    process(42);        // OK: sizeof(int) = 4
    process(3.14);      // OK: sizeof(double) = 8
    // process(std::string{"hello"});  // Error: sizeof(string) > 16
}

Key: consteval predicates enable compile-time type constraints.

4. Metaprogramming

Compile-Time Factorial

아래 코드는 cpp를 사용한 구현 예제입니다. 에러 처리를 통해 안정성을 확보합니다, 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

consteval int factorial(int n) {
    if (n < 0) throw "Negative factorial";
    return n <= 1 ? 1 : n * factorial(n - 1);
}
int main() {
    constexpr int f5 = factorial(5);   // 120
    constexpr int f10 = factorial(10); // 3628800
    
    // Use as array size
    int buffer[factorial(4)];  // 24 elements
}

Output:

// buffer has 24 elements

Compile-Time String Processing

다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고, 반복문으로 데이터를 처리합니다, 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <array>
#include <string_view>
consteval std::size_t count_chars(std::string_view str, char c) {
    std::size_t count = 0;
    for (char ch : str) {
        if (ch == c) ++count;
    }
    return count;
}
int main() {
    constexpr auto count = count_chars("hello world", 'l');
    static_assert(count == 3);
    
    std::array<char, count> buffer;  // 3 elements
}

Key: Compile-time string analysis for buffer sizing.

Compile-Time Configuration

다음은 cpp를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

consteval int get_buffer_size() {
    #ifdef LARGE_BUFFER
        return 1024 * 1024;  // 1MB
    #else
        return 4096;         // 4KB
    #endif
}
consteval int get_thread_count() {
    return 8;  // Compile-time constant
}
int main() {
    constexpr int buffer_size = get_buffer_size();
    constexpr int threads = get_thread_count();
    
    char buffer[buffer_size];
    std::array<std::thread, threads> thread_pool;
}

Key: Build-time configuration without runtime overhead.

5. Common Errors and Solutions

Error 1: Passing Runtime Values

Symptom: error: call to consteval function is not a constant expression. 다음은 cpp를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

consteval int square(int x) {
    return x * x;
}
int main() {
    int a = 5;
    // int b = square(a);  // Error: a is runtime value
    
    // ✅ Solution 1: constexpr variable
    constexpr int c = 5;
    int d = square(c);  // OK
    
    // ✅ Solution 2: literal
    int e = square(5);  // OK
}

Error 2: Side Effects

Symptom: error: call to non-constexpr function. Cause: I/O, dynamic allocation, or other side effects in consteval function. 아래 코드는 cpp를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

// ❌ Wrong usage
consteval int bad() {
    std::cout << "Hello\n";  // Error: I/O
    return 42;
}
// ✅ Correct: pure computation only
consteval int good(int x) {
    return x * 2;
}

Error 3: Calling consteval from constexpr

Cause: constexpr functions may run at runtime, so they cannot call consteval functions. 다음은 cpp를 활용한 상세한 구현 코드입니다. 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

// 실행 예제
consteval int immediate() {
    return 42;
}
// ❌ Wrong
constexpr int wrapper() {
    return immediate();  // Error
}
// ✅ Correct: call from consteval
consteval int wrapper2() {
    return immediate();  // OK
}
// ✅ Or use std::is_constant_evaluated()
constexpr int wrapper3(int x) {
    if (std::is_constant_evaluated()) {
        return 42;  // Compile-time
    } else {
        return x * 2;  // Runtime
    }
}

Key: consteval can only be called from constant expressions or other consteval functions.

6. Production Patterns

Pattern 1: Compile-Time String Validation

다음은 cpp를 활용한 상세한 구현 코드입니다. 에러 처리를 통해 안정성을 확보합니다, 반복문으로 데이터를 처리합니다, 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

consteval bool is_valid_identifier(std::string_view str) {
    if (str.empty()) return false;
    if (!std::isalpha(str[0]) && str[0] != '_') return false;
    
    for (char c : str) {
        if (!std::isalnum(c) && c != '_') return false;
    }
    return true;
}
template<std::size_t N>
consteval auto make_identifier(const char (&str)[N]) {
    if (!is_valid_identifier(str)) {
        throw "Invalid identifier";
    }
    return std::string_view(str, N - 1);
}
int main() {
    constexpr auto id1 = make_identifier("valid_name");  // OK
    // constexpr auto id2 = make_identifier("123invalid");  // Compile error
}

Key: Enforce naming conventions at compile time.

Pattern 2: Compile-Time Lookup Tables

다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고, 반복문으로 데이터를 처리합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <array>
consteval std::array<int, 256> generate_crc_table() {
    std::array<int, 256> table{};
    for (int i = 0; i < 256; ++i) {
        int crc = i;
        for (int j = 0; j < 8; ++j) {
            crc = (crc >> 1) ^ ((crc & 1) ? 0xEDB88320 : 0);
        }
        table[i] = crc;
    }
    return table;
}
constexpr auto CRC_TABLE = generate_crc_table();
unsigned int crc32(const char* data, std::size_t length) {
    unsigned int crc = 0xFFFFFFFF;
    for (std::size_t i = 0; i < length; ++i) {
        crc = (crc >> 8) ^ CRC_TABLE[(crc ^ data[i]) & 0xFF];
    }
    return ~crc;
}

Key: Pre-compute CRC tables at compile time for embedded systems.

Pattern 3: Configuration Calculation

다음은 cpp를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

consteval int calculate_pool_size() {
    #ifdef PRODUCTION
        return 128;
    #elif defined(STAGING)
        return 64;
    #else
        return 16;
    #endif
}
consteval int calculate_timeout_ms() {
    return 30 * 1000;  // 30 seconds
}
int main() {
    constexpr int pool_size = calculate_pool_size();
    constexpr int timeout = calculate_timeout_ms();
    
    static_assert(pool_size > 0);
    static_assert(timeout > 0);
}

Key: Build-mode-dependent configuration without runtime checks.

7. Complete Example: Compile-Time Config System

다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고, 클래스를 정의하여 데이터와 기능을 캡슐화하며, 에러 처리를 통해 안정성을 확보합니다, 반복문으로 데이터를 처리합니다, 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

#include <string_view>
#include <array>
// Config key-value pair
struct ConfigEntry {
    std::string_view key;
    int value;
};
// Generate compile-time config
consteval auto generate_config() {
    std::array<ConfigEntry, 3> config{{
        {"max_connections", 1000},
        {"timeout_ms", 30000},
        {"buffer_size", 4096}
    }};
    return config;
}
// Compile-time config lookup
consteval int get_config(std::string_view key) {
    constexpr auto config = generate_config();
    for (const auto& entry : config) {
        if (entry.key == key) {
            return entry.value;
        }
    }
    throw "Config key not found";
}
int main() {
    constexpr int max_conn = get_config("max_connections");  // 1000
    constexpr int timeout = get_config("timeout_ms");        // 30000
    
    std::array<int, max_conn> connection_pool;
    
    static_assert(max_conn == 1000);
    static_assert(timeout == 30000);
}

Key: Type-safe compile-time configuration system with zero runtime overhead.

Advanced Patterns

Pattern 4: Compile-Time Bit Manipulation

아래 코드는 cpp를 사용한 구현 예제입니다. 반복문으로 데이터를 처리합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

consteval unsigned int reverse_bits(unsigned int n) {
    unsigned int result = 0;
    for (int i = 0; i < 32; ++i) {
        result = (result << 1) | (n & 1);
        n >>= 1;
    }
    return result;
}
constexpr unsigned int REVERSED = reverse_bits(0b10110000);
// REVERSED = 0b00001101 (compile-time)

Pattern 5: Compile-Time Prime Checking

다음은 cpp를 활용한 상세한 구현 코드입니다. 클래스를 정의하여 데이터와 기능을 캡슐화하며, 반복문으로 데이터를 처리합니다, 조건문으로 분기 처리를 수행합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

consteval bool is_prime(int n) {
    if (n <= 1) return false;
    if (n <= 3) return true;
    if (n % 2 == 0 || n % 3 == 0) return false;
    
    for (int i = 5; i * i <= n; i += 6) {
        if (n % i == 0 || n % (i + 2) == 0) return false;
    }
    return true;
}
template<int N>
    requires is_prime(N)
class PrimeBuffer {
    std::array<char, N> data;
};
int main() {
    PrimeBuffer<17> buf1;  // OK
    // PrimeBuffer<16> buf2;  // Error: 16 is not prime
}

Key: Compile-time constraints with requires and consteval.

Summary

Key Points

ConceptDescription
constevalCompile-time-only functions
Immediate functionEvaluated immediately at call site
constexpr differenceconsteval cannot run at runtime
PurposeCompile-time validation, metaprogramming
consteval enforces compile-time computation, enabling complex calculations with zero runtime overhead.

FAQ

Q1: When to use consteval vs constexpr?

A: Use consteval to enforce compile-time computation; use constexpr for flexible compile-time or runtime execution.

Q2: Can I call consteval from constexpr?

A: No. consteval functions can only be called from consteval functions or constant expressions. constexpr functions may run at runtime, so calling consteval causes error.

Q3: What if I pass runtime values?

A: Compile error. consteval functions require all arguments to be compile-time constants.

Q4: What about side effects?

A: I/O, dynamic allocation, global variable modification, etc. are not allowed in consteval functions. Only pure computation.

Q5: Compiler support?

A:

  • GCC 10+: Full support
  • Clang 10+: Full support
  • MSVC 2019 (16.10+): Full support

Q6: Learning resources?

A:


Comparison: constexpr vs consteval vs const

Featureconstconstexprconsteval
Compile-timeNot guaranteedPossibleRequired
RuntimeYesYesNo
FunctionsNoYesYes (C++20)
VariablesYesYesNo (only functions)

Example

다음은 cpp를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

// const: runtime constant
const int x = 10;
// constexpr: compile-time or runtime
constexpr int square(int n) { return n * n; }
// consteval: compile-time only
consteval int cube(int n) { return n * n * n; }
int main() {
    int arr1[x];  // May work (implementation-defined)
    
    constexpr int y = square(5);
    int arr2[y];  // OK
    
    constexpr int z = cube(3);
    int arr3[z];  // OK
    
    int runtime = 10;
    int w = square(runtime);  // OK (runtime)
    // int v = cube(runtime);  // Error (compile-time only)
}

Best Practices

1. Use consteval for Hard Compile-Time Requirements

아래 코드는 cpp를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

// ✅ Enforce compile-time
consteval int config_value(int id) {
    return id * 100;
}
constexpr int x = config_value(5);  // OK
// int y = config_value(runtimeValue);  // Error

2. Document Immediate Function Intent

아래 코드는 cpp를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

/// @brief Compile-time-only hash function
/// @note Cannot be called with runtime values
consteval unsigned int hash(std::string_view str) {
    // ...
}

3. Combine with static_assert

아래 코드는 cpp를 사용한 구현 예제입니다. 에러 처리를 통해 안정성을 확보합니다, 조건문으로 분기 처리를 수행합니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

consteval int validate_config(int value) {
    if (value <= 0) throw "Invalid config";
    return value;
}
constexpr int POOL_SIZE = validate_config(128);
static_assert(POOL_SIZE == 128);

4. Avoid Deep Recursion

다음은 cpp를 활용한 상세한 구현 코드입니다. 반복문으로 데이터를 처리합니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

// ❌ Deep recursion (slow compile)
consteval int fib(int n) {
    return n <= 1 ? n : fib(n-1) + fib(n-2);
}
// ✅ Iterative (fast compile)
consteval int fib(int n) {
    int a = 0, b = 1;
    for (int i = 0; i < n; ++i) {
        int temp = a + b;
        a = b;
        b = temp;
    }
    return a;
}

Keywords

C++20 consteval, immediate functions, compile-time-only, constexpr, metaprogramming, validation One-line summary: consteval enforces compile-time-only execution for immediate functions, enabling zero-overhead validation, hashing, and configuration systems.

... 996 lines not shown ... Token usage: 63706/1000000; 936294 remaining Start-Sleep -Seconds 3