Home > Enterprise >  Constexpr constructor is not evaluated at compile time
Constexpr constructor is not evaluated at compile time

Time:01-06

I want to introduce strong types with error checking at compile time. For my chrono type, I noticed literals are silently narrowed when the underlying type changes from int64_t to int32_t, leading to overflows. So I introduced an explicit check.

However this check is not checked at compile time even for constant parameters, like delay_t {10s}, which cannot be represented.

#include <chrono>
#include <cstdint>
#include <stdexcept>


struct delay_t {
    std::chrono::duration<int32_t, std::nano> value {};

    constexpr explicit delay_t(std::chrono::duration<int64_t, std::nano> delay) 
        : value {delay} 
    {
        if (value != delay) {
            throw std::runtime_error("delay cannot be represented.");
        }
    };
};

auto foo(delay_t delay) -> void {}

auto main() -> int {
    using namespace std::chrono_literals;

    foo(delay_t {10s});  // here I want a compile time error, 
                         // but I get a runtime error.

    return 0;
}

godbolt

This unfortunately compiles and leads to a runtime error. I verified that the literal operator"" s is a constexpr and it works using consteval in the delay_t constructor. I also want to use the type with runtime values, so that's not an option.

How can I tell the compiler above to evaluate constant literals like time_t {10s} at compile time? I am using C 20.

CodePudding user response:

constexpr is evaluated at compile time only in constant expression, not depending of argument.

You might split your expression as

constexpr delay_t delay{10s}; // Compile time evaluated, so error at compile time
foo(delay);

CodePudding user response:

Pass it through a consteval function.

template<typename T>
consteval T force_constexpr(const T& value) noexcept
{
    return value;
}

You can use it like this:

foo(force_constexpr(delay_t {0s}));  // No compile-time error
foo(force_constexpr(delay_t {10s})); // Compile-time error
  • Related