Skip to main content
The if consteval statement is a C++23 control flow mechanism that determines whether the current execution context is a manifestly constant-evaluated context. It allows a constexpr function to execute distinct logic depending on whether it is being evaluated by the compiler during translation or by the CPU at run-time.

Syntax

Unlike standard if statements, if consteval does not evaluate a parenthesized condition. It acts as a standalone keyword construct. According to the C++23 grammar (if consteval compound-statement else statement), the true branch strictly requires a compound statement (a brace-enclosed block), while the else branch accepts any standard statement.
C++23 also supports a negated form to invert the logic:

Technical Mechanics

Context Resolution The statement resolves to true if the evaluation occurs within a manifestly constant-evaluated context. This includes contexts that strictly require a constant expression (e.g., initializing a constexpr variable, template arguments, or array bounds), as well as execution inside an immediate (consteval) function. If the function containing the statement is invoked at run-time, the statement resolves to false. Immediate Function Context The most critical technical mechanic of if consteval is that its true branch establishes an immediate function context. This allows developers to call consteval (immediate) functions from within a standard constexpr function, passing the enclosing function’s parameters as arguments, without triggering immediate evaluation errors. Compilation and Well-Formedness Unlike if constexpr, if consteval does not produce “discarded statements”. Both the if and else branches are fully parsed and compiled, and both branches must be well-formed C++ code regardless of the context in which the function is invoked. The compiler does not ignore the syntax or semantic validity of the untaken branch. Grammar Requirements The grammar explicitly mandates a compound statement for the if consteval branch. Single-statement bodies without braces result in a syntax error. However, the else branch is a standard statement, meaning it can be a single unbraced statement, a braced block, or another if statement.

if consteval vs. std::is_constant_evaluated()

if consteval was introduced to replace std::is_constant_evaluated(), a C++20 standard library constexpr function, due to two significant technical limitations of the library function:
  1. The consteval Invocation Error: Using if (std::is_constant_evaluated()) does not establish an immediate function context. Consequently, any call to a consteval function inside that block is treated as an immediate invocation and must be evaluated immediately. If this consteval call depends on the enclosing function’s parameters, compilation fails because function parameters are not constant expressions. (A call independent of parameters, such as consteval_func(42), compiles fine). if consteval solves this at the language level by making the block an immediate function context, which defers the evaluation and allows parameters to be passed to consteval functions.
  2. The Tautology Trap: If a developer mistakenly combined the C++20 function with if constexpr, it resulted in a tautology:
// ANTI-PATTERN (C++20) if constexpr (std::is_constant_evaluated())