On Sat, 8 May 2021, 20:32 Nevin Liber, <nevin@cplusplusguy.com> wrote:
On Sat, May 8, 2021 at 2:18 PM Jonathan Wakely <cxx@kayari.org> wrote:

I think adding std::unreachable(); after the assertion would work for that purpose.

If I'm reading it correctly, the paper says that unreachable is not allowed in a constant expression (because calling it is UB). 

It means that unreachable() cannot be called during constant evaluation. It is allowed in a constexpr function as long as it's not reached. That's the same as falling off the end of a function, isn't it? I don't think it changes anything.

During constant evaluation, if you reach the end of a non-void function it's an error. Reaching a call to unreachable would be the same.


That is a breaking change for calling assert in a constexpr context [assertions.assert].  And even if we fix the one in the standard, how can users write their own?


No, because I'm not suggesting adding it to assert. I said add it after the assertion, i.e. in the function containing the assertion.

constexpr int f(bool x)
{
  if (x)
    return 0;
  assert(false);
  // std::unreachable();
}

If you call f(false) in a constant expression, this is already ill-formed because either the assert calls abort which is not a constexpr function, or you fall off the end which is UB so not allowed in constexpr. If you call f(false) at runtime, either it aborts, or has UB.

If you call f(true) it's fine, in any context 

Uncommenting the last line changes nothing, except the compiler won't warn about possible runtime UB in NDEBUG builds, because you've told it not to.

Am I misunderstanding your point?