5 ms·
> ...`std::unreachable`. But shouldn't this be a compiler directive? Probably "committee pragmatism", a stdlib change might be easier to get approved than a la
by flohofwoe 4y ago
> ...`std::unreachable`. But shouldn't this be a compiler directive?
Probably "committee pragmatism", a stdlib change might be easier to get approved than a language change, and compilers already have builtins for this, they're just not compatible (but the differences can be wrapped in a macro, and since C++ doesn't like to expose macros, it's probably still a macro, but hidden inside a stdlib template).
FWIW it looks like C23 will also just get a macro:
https://thephd.dev/ever-closer-c23-improvements#unreachable-macro-for-optimization-and-code-improvement https://thephd.dev/ever-closer-c23-improvements#unreachable-...
- gpderetta 4y agoAlso from a standardization point of view there isn't really much of a difference between a builtin and a plain library function. Library functions can be scoped in namespaces and that's a plus.
- addaon 4y agostd::unreachable() feels like it's what std::assert(false) should be, except that std::assert(false) is bizarrely defined (as a no-op) when NDEBUG is defined. This is one of those strange cases where the spec defines behavior that I'd strongly expect to be undefined.
- int_19h 4y agoWhat's bizarre about asserts being disabled if you explicitly ask for it?
- addaon 4y agoI'm not asking for the assert to be disabled. I'm asking for debugging features to be disabled. (NDEBUG == "no debug.") The debugging feature of an assert statement is that it performs work to check if the assertion is true and provides diagnostics if not. Disabling the debugging feature of an assert would, in my mind, make it purely an assertion -- an assumption that the compiler can count on (since this is true by design and demonstrated during debugging). Which is to say, it becomes undefined (contrary to compiler assumptions) if the condition is false. Another way of thinking of this: With NDEBUG undefined, the sequence `assert(condition); if(!condition) action();` is perfectly reasonable and equivalent to the naked assert. But, because assert(false) is defined, defining NDEBUG changes the semantics of the code, with the two examples having identical behavior when NDEBUG is unset, and different behavior when NDEBUG is set. This is contrary to my understanding of the intent of NDEBUG, to suppress debugging information without changing semantics. A third view: With NDEBUG undefined (which is normal for test and development), /I have no way of testing what happens past an assert(false)/. If I then define NDEBUG for a release build, I'm by definition exposing my user to untested code. The compiler might (with a defined assert(false)) define the behavior of this new code, /but I cannot, since I can't test it./ It just makes more sense to acknowledge that anything past an event horizon is undefinable, and call it undefined.
- randomNumber7 4y agoThe D Programming language actually uses assert(0) in that way. Except its not undefined behaviour if the code is reached in release builds. The compiler will put in a special assembly instruction which chrashes the programm.
- int_19h 4y agoThe sole intent of NDEBUG in the Standard is to suppress assert(). There's a reasonable argument to be made here that it's poorly named (although I suspect that ANSI simply standardized existing practice here, as they did with much of the standard).
- 3836293648 4y agoSurely you mean ISO and not ANSI? Were such ugly hacks already a part of C89?
- pjscott 4y agoI checked LLVM's libc++ source, and it's an inline void function defined in a header, which contains only a call to __builtin_unreachable() when available or std::abort() otherwise.