2

Related:

I want to have an assert macro that when possible is a static_assert, but falls back to assert when static_assert isn't possible. My sense is that std::is_constant_evaluated() should help with this, by being intended to allow constexper execution to use a different implementation than runtime execution, but everything I've tried like that fails:

#define ASSERT0(cond) \
if (std::is_constant_evaluated()) { \
    static_assert((cond)); \
} else { \
    assert((cond)); \
}

#define ASSERT1(cond) \
if constexpr (std::is_constant_evaluated()) { \
    static_assert((cond)); \
} else { \
    assert((cond)); \
}

#define ASSERT2(cond) \
if consteval { \
    static_assert((cond)); \
} else { \
    assert((cond)); \
}

https://godbolt.org/z/KzWfxMdMd

Fundamentally, as @BoP points out, the challenge is: when a function is being evaluated in a constexpr context, its arguments still aren't integral constants (https://godbolt.org/z/co93nc59h).

I'm new to std::is_constant_evaluated(). Is there something I'm missing? Should it be able to be used to switch between static_assert and assert?

Ben
  • 9,184
  • 1
  • 43
  • 56
  • 1
    please also include the example of how it fails in the question – 463035818_is_not_an_ai May 03 '22 at 17:56
  • 3
    `if constexpr (std::is_constant_evaluated())` will always be true, as `if constexpr` is a constant expression. You always want to use the form `if (std::is_constant_evaluated())` – NathanOliver May 03 '22 at 17:57
  • 1
    And if you *don't* use `if constexpr` , both parts of the if-else must always compile. Catch-22! – BoP May 03 '22 at 18:48
  • @BoP exactly. I updated the question a little. Fundamentally it surprises me that in a function being evaluated in a constexpr context, the locals aren't integral constant expressions. Even if it's `consteval int foo(int x)` which is very surprising to me: https://godbolt.org/z/n83YvM9vT – Ben May 03 '22 at 19:45
  • 1
    I'm not all that familiar with `consteval`, but a `constexpr` function can be used in a non-const runtime context. However, the `static_assert` must still be evaluated when compiling the function, not when executing the call. A somewhat similar problem is that `if constexpr (true) { ok(); } else { static_assert(false); } ` will trigger the assert, even though it can never be executed. – BoP May 03 '22 at 20:27

0 Answers0