Ch7.4: if consteval

Overview

if consteval checks whether the current function call is being evaluated in a constant expression context. It allows a function to behave differently when executed at compile time versus runtime.

Unlike if constexpr, which depends on a constant expression value, if consteval depends on how the function is being evaluated.

1. Basic example

When a function is evaluated at compile time, the if consteval branch is taken. When evaluated at runtime, the else branch is taken.


#include <fast_io.h>

int compute(int x)
{
    using namespace ::fast_io::iomnp;

    if consteval
    {
        print("computed at compile time\n");
        return x * 2;
    }
    else
    {
        print("computed at runtime\n");
        return x + 2;
    }
}

The compiler chooses the branch based on the evaluation context.

2. Forcing compile‑time evaluation

A constexpr variable forces its initializer to be evaluated at compile time. This means the if consteval branch will be taken.


constexpr int a = compute(10);  // compile-time evaluation
int b = compute(10);            // runtime evaluation

The first call prints “computed at compile time”, and the second prints “computed at runtime”.

3. Why this is useful

if consteval is useful when a function must:

For example, you may want to forbid certain operations when the function is evaluated at compile time.


#include <fast_io.h>

int safe_divide(int a, int b)
{
    using namespace ::fast_io::iomnp;

    if consteval
    {
        if(b == 0)
            print("error: division by zero in constant expression\n");
    }

    return a / b;
}

This allows compile‑time checks without affecting runtime behavior.

4. Contrast with if constexpr

if constexpr depends on a constant expression value:


if constexpr(flag) { ... }

if consteval depends on the evaluation context:


if consteval { ... }

They solve different problems:

Key takeaways