C++ Logo

std-proposals

Advanced search

std::error magic function

From: connor horman <chorman64_at_[hidden]>
Date: Fri, 6 Mar 2020 09:46:56 -0500
C++ has a number of features which are available at compile time via
constexpr, however none of those features allow for error checking and
handling (in all cases, such as using throw, the evaluation is only
ill-formed if it needs to be a constant expression, otherwise it downgrades
to a runtime error).

I propose a function std::error, which takes a std::string_view diagnostic,
to help solve this, by allowing constexpr userss

If std::error is evaluated as part of an expression that is not *manifestly
constant evaluated* std::error throws an exception of some type, probably
std::logic_error, or a new exception type derived from it. The what message
would be the parameter.
If std::error is evaluated as part of an expression that is *manifestly
constant evaluated* the program is ill-formed, with the diagnostic being
implementation-defined, but including the parameter in some manner.
This is a stricter standard than "Not a core constant expression", as it
will have different semantics on potentially constant constructible values,
like const integral and const enumeration values, as well as statics.
Here, the check is necessarily equivalent to the one performed by
std::is_constant_evaluated.

Currently it is not possible to implement std::error in a way that it will
work with initializing non-constexpr variables. Throwing an exception
simply downgrades to runtime, only erroring if the result is needed at
compile time.
In most cases std::error would be called, its guaranteed that the
downgraded call will trigger at runtime, thereby losing a potentially
useful user-triggered diagnostic. A solution has previously been to throw
an undefined identifier, so a downgrade would be caught at link time,
however this is a hack at best, and non-working at worst. The standard does
provides that odr violations do not require a diagnostic (though most
modern compilers can issue a link time diagnostic). I chose this, rather
than making the exception ill-formed rather than downgrading, as explicitly
throwing an exception to downgrade specific cases to runtime when possible
may be desired (less such cases exist, thanks to
std::is_constant_evaluated, but they may still exist, and breaking existing
code is always fun).

I don't see a huge barrier to implementing this in compiler space, I could
probably work on a reference implementation when I am finished various
things with llvm.

Possible alternatives: Rather than throwing at runtime, an alternative
would be to emit the runtime diagnostic message and call std::terminate.
Another alternative would be a function std::compiler_error, which simply
emits a compiler diagnostic when evaluated in a constexpr context, but it
suffers from the problem of "What happens if its evaluated at runtime". It
could be immediate, but that disqualifies it from being used at in
constexpr functions, where it could be evaluated at runtime. I believe that
this proposal satisfies that problem, by saying that it downgrades and
throws if the standard doesn't want the result at compile time.


Proposed Signature: [[noreturn]] constexpr void error(std::string_view
diagnostic);

Received on 2020-03-06 08:49:54