curiousguy12
curiousguy12

Reputation: 1807

static_assert rejected in consteval constructor

struct test {
    int var;

    consteval test(int i) : var{i}
    {
        static_assert(i == 3);
    }
};

int main()
{
    constexpr test t{3};
}

This is rejected with:

$ g++ c.cpp -std=c++20
c.cpp: In constructor ‘consteval test::test(int)’:
c.cpp:8:25: error: non-constant condition for static assertion
    8 |         static_assert(i == 3);
      |                       ~~^~~~
c.cpp:8:23: error: ‘i’ is not a constant expression
    8 |         static_assert(i == 3);
      |                       ^

Why can't I use static_assert if the constructor is guaranteed to be evaluated at compile time ?

Upvotes: 1

Views: 133

Answers (2)

Brendan
Brendan

Reputation: 61

Function parameters are not usable as constant expressions. If you want to do compile-time checking you can try to do some workarounds though.

Take this code for example:

consteval void static_assert_num(auto number_to_check, int asserted_value)
{
    number_to_check /= (number_to_check == asserted_value);    
}

struct test {
    int var;

    consteval test(int i) : var{i}
    {
        static_assert_num(i, 3);
    }
};

int main()
{
    constexpr test t{3}; // no error
    constexpr test t{4}; // compilation error
}

Not the cleanest code, and maybe someone can come up with something better, but this seems to do the job. We can abuse the fact that constexpr doesn't allow for UB, so we just divide by zero to force an error (more examples found in this thread).

Upvotes: 3

user17732522
user17732522

Reputation: 76889

It doesn't work that way.

When you write static_assert(i == 3); in the function definition, then you are asking the compiler to check that condition to be true while compiling the definition of the function. At that point i is not known.

Formally, i == 3 must itself be a constant expression, but i is not usable in constant expressions because it is not a compile-time constant (function parameters never are).

Upvotes: 5

Related Questions