c++c++20compile-timec++23static-assert

Check at compile time that a function call triggers a `static_assert(false)`


I have a template function with several type parameters and depending on those types, the function "calls" an static_assert(false). I want to know when my code fails to compile for specific combinations of type parameters when running unit tests.

Is there any way to detect at compile time that a static_assert fails, without the compiler issuing a compiler error, and wrap this detection into a function that can be used at run time.

I do not want to simply let the compiler fail to compile the code, but rather I want to run tests that pass when the code would fail to compile.

Question

Is it possible to have a function that says

all while the compiler successfully compiles the code, even the bits that the function says should not compile?

Some code

For example, consider the function:

template <typename T>
constexpr void problematic_code()
{
    if constexpr (std::is_integral_v<T>) {
        static_assert(false, "This code should not compile!");
    }
}

The code does not compile whenever I write any of the following:

problematic_code<int>();
problematic_code<char>();
// ...

This is OK! But, is there any mechanism in C++20/23 that I can use to write a function such as:

template <typename T>
constexpr bool will_problematic_code_compile() {
    if (calling problematic_code<T>() reaches static_assert(false)) {
        return false;
    }
    return true;
}

Then, I would like to write a test such as:

TEST_CASE("") {
    CHECK(not will_problematic_code_compile<int>());
    CHECK(not will_problematic_code_compile<char>());
    CHECK(will_problematic_code_compile<float>());
}

I tried requires:

template <typename T>
constexpr bool will_problematic_code_compile()
{
    return requires { problematic_code<T>(); };
}

but this always returns true.

Other answers

The suggested answer does not help since it does not consider C++20/23, and it tries to discuss the right way to use static_assert, which is not what I'm interested in.


Solution

  • No, this is impossible. Compilers aren’t designed to “recover” from errors inside function bodies (no SFINAE there!), and one would expect to be able to static_assert in a function that also wouldn’t compile for other reasons.