The consensus of the Toronto meeting's EWG was that std::unreachable, intentionally causing undefined behavior, should have two forms:
[[noreturn]] void unreachable();
[[noreturn]] void unreachable($literal string$);
The intent is similar to that of static_assert: have a diagnostic message that could be shown when an unreachable statement is executed in a debug build.
What I'm wondering is how unreachable should take that parameter. The obvious would be the following:
[[noreturn]] void unreachable(const char *message);
This would allow literal strings, but it would also allow constructions like the following:
void f(int i) {
switch (i) {
case 0:
case 2:
something();
break;
default: {
char message[64];
std::snprintf(message, sizeof(message), "unknown value: %d", i);
std::unreachable(message);
}
}
}
Should such constructions be allowed, or should a literal string be required? If a literal string, how would that even be enforced, given that this is a library function?
In optimized builds in a mode in which the compiler does not output a diagnostic message, the call to std::snprintf could be elided by a smart compiler; if the compiler knows that the only observable effect of std::snprintf is to modify "message", it could elide the call because std::unreachable is presumably implemented as an inline function.
I was considering wording such as the following, under the assumption that a runtime value of "message" is allowed:
"If an implementation issues a diagnostic upon the execution of std::unreachable(), and the 'message' parameter is present, the diagnostic message should include the characters of 'message' that are in the execution character set."
Assuming (correctly IMO) that the 'message' parameter is a `const char*`, it points to a null-terminated sequence of characters, which by definition are in the execution character set. The translation of a string literal (if any) from the source character set into a sequence of bytes in the execution character set has, by runtime, already happened; and therefore std::unreachable() doesn't need to do anything special to deal with it.–Arthur