> ## Documentation Index
> Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt
> Use this file to discover all available pages before exploring further.

# C++ Consteval Function

A `consteval` function, introduced in C++20, is an *immediate function* that is strictly guaranteed to be evaluated at compile-time. Unlike `constexpr`, which acts as a dual-purpose function capable of both compile-time and runtime evaluation, a `consteval` function mandates that every invocation produces a valid constant expression, unless the invocation occurs within an immediate function context. If the compiler cannot evaluate the function at compile-time outside of such a context, the program is ill-formed and will result in a compilation error.

## Syntax

The `consteval` specifier is placed in the function declaration, preceding the return type.

```cpp theme={"dark"}
consteval return_type function_name(parameters) {
    // function body
}
```

## Core Mechanics and Constraints

To qualify as an immediate function, a `consteval` function must adhere to strict structural and contextual rules:

* **Constant Expression Requirement & Immediate Function Context:** Outside of an immediate function context, every call to a `consteval` function must yield a compile-time constant, meaning all arguments passed to it must be constant expressions. However, within an **immediate function context** (such as the body of another `consteval` function or an immediate-escalating function), this restriction is lifted. In this context, a `consteval` function can freely call other `consteval` functions using its own runtime parameters. This exemption is critical for composing immediate functions without requiring intermediate variables to be strictly `constexpr`.
* **Type Requirements:** While C++20 strictly mandated that both the return type and all parameter types be literal types, C++23 (via P2448R2) relaxed this rule. Parameter and return types are no longer required to be literal types at the declaration level, though the function must still be capable of producing a constant expression during actual evaluation.
* **Implicit Inline:** A `consteval` function is implicitly `inline`.
* **Address Restrictions:** You cannot take the address of a `consteval` function, nor can you form a pointer or reference to it, unless the context in which you are doing so is an immediate function context.
* **Prohibited Contexts:** A `consteval` function cannot be a destructor, a coroutine, or an allocation/deallocation function. Note that while C++20 introduced `constexpr` destructors, the standard explicitly forbids destructors from being declared `consteval`.
* **Body Restrictions:** The function body is subject to the same restrictions as a `constexpr` function. Uninitialized variables are permitted provided they are not read before being initialized. As of C++23, the body may also contain `goto` statements, labels, and definitions of variables of non-literal types, strictly provided that the specific code paths containing these constructs are not executed during constant evaluation.

## `consteval` vs. `constexpr`

The distinction between `constexpr` and `consteval` lies in the strictness of the evaluation context:

* **`constexpr`**: Indicates that a function *can* be evaluated at compile-time if provided with constant expressions. If provided with runtime variables, it degrades to a standard runtime function.
* **`consteval`**: Indicates that a function *must* be evaluated at compile-time. It has no runtime equivalent and will never generate runtime machine code for the function call itself.

## Evaluation Behavior and Composition

The following code block demonstrates the strict evaluation rules and the mechanics of the immediate function context:

```cpp theme={"dark"}
consteval int compute_multiplier(int a, int b) {
    return a * b;
}

consteval int compose_computation(int x, int y) {
    // Valid: This is an immediate function context.
    // 'x' and 'y' are not constant expressions themselves, but passing 
    // them to another consteval function is perfectly legal here.
    return compute_multiplier(x, y) + 10;
}

int main() {
    // Valid: Both arguments are literal constants. Evaluated at compile-time.
    constexpr int result1 = compose_computation(5, 10); 
    
    // Valid: The result can be assigned to a non-constexpr variable, 
    // but the function execution still occurs entirely at compile-time.
    int result2 = compose_computation(4, 8); 

    int runtime_val = 5;
    
    // Ill-formed: 'runtime_val' is not a constant expression, and this call 
    // is not inside an immediate function context.
    // int result3 = compute_multiplier(runtime_val, 10); // Compilation Error
    
    return 0;
}
```

## Immediate Escalation (C++23 Context)

Introduced in C++23, *immediate escalation* is a mechanism where specific functions automatically promote to `consteval` (immediate functions) if they invoke an immediate function in a way that cannot be evaluated at compile-time (e.g., using non-constant arguments).

Crucially, not all functions escalate. Escalation is strictly limited to **immediate-escalating functions**, which are defined as:

1. **Functions resulting from the instantiation of a parameterized entity** (such as a function template or a member of a class template) defined with the `constexpr` specifier. A standard, non-`constexpr` parameterized entity will *not* escalate and will produce a hard compilation error if it invokes a `consteval` function with non-constant arguments.
2. **Lambdas** (specifically, the closure type's `operator()`, provided it is not explicitly declared `consteval`).
3. **Defaulted special member functions** that are *not* explicitly declared with the `constexpr` specifier. If a defaulted special member function is explicitly declared `constexpr`, it behaves like a standard `constexpr` function and does not escalate.

If one of these eligible functions invokes a `consteval` function with non-constant arguments, it escalates to `consteval` itself, propagating the strict compile-time evaluation requirement up the call stack. A standard, non-templated `constexpr` function is never an immediate-escalating function. This strict boundary exists to prevent silent ABI and API breaks that would occur if a standard function signature implicitly changed its linkage and runtime availability.

<div
  style={{ 
display: "flex", 
justifyContent: "space-between", 
alignItems: "center", 
maxWidth: "754px", 
padding: "1rem 0",
marginBottom: "24px"
}}
>
  <span style={{ fontWeight: "bold", fontSize: "1.25rem", color: "var(--tw-prose-headings)", fontFamily: "Inter, ui-sans-serif, system-ui, sans-serif" }}>Tired of Poor C++ Skills? Fix That With Deep Grasping!</span>

  <a
    href="https://syntblaze.com"
    target="_blank"
    style={{ 
  marginLeft: "24px",
  textDecoration: "none", 
  backgroundColor: "#007AFF",
  color: "#ffffff", 
  padding: "6px 16px", 
  borderRadius: "16px",
  fontSize: "0.9rem",
  fontWeight: "600",
  textAlign: "center",
  transition: "background-color 0.2s ease"
}}
  >
    Learn More
  </a>
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/skill-tracking.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=b9b0305c93bb501c9e767b5c76c88835" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/skill-tracking.png" />

  <img src="https://mintcdn.com/syntblazellc/23tyuOzaWS88qFlc/images/nuggets.png?fit=max&auto=format&n=23tyuOzaWS88qFlc&q=85&s=c86c80197299762989e9b882419b2109" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/nuggets.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/bite-sized-exercises.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=a65f9a38c37ff28ab73ed783c53c60e3" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/bite-sized-exercises.png" />
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap", marginTop: "12px" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/mastery-chain.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=748a1763454713e679260fbb95f154a2" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/mastery-chain.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-previews.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=242f61448ff5dd6deaaab2dccc13b507" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-previews.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-explanations.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=cf0fc1c31f9cd0fc26716781be05fbc9" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-explanations.png" />
</div>
