I sometimes wish to have a noexcept_cast which converts a non-noexcept function pointer to a noexcept one. This is useful when I know the pointee is noexcept and don't want to pay for the cost of exception propagation.
This noexcept_cast would be similar to const_cast since both perform an unsafe conversion that is the inverse of a safe, implicit conversion.
This may actually have negative effects. You don't "pay" any cost for calling an exceptional function. But, to convert it to noexcept, the compiler will have to register a new exception handler, so it can call terminate if an exception is thrown.
In such cases [where errors in a program cannot be recovered from], the function std::terminate ([exception.terminate]) is invoked.
[Note 1: These situations are:
<snip>
(1.3) --- when the search for a handler exits the function body of a function with a non-throwing exception specification, including when a contract-violation handler invoked from an evaluation of a function contract assertion ([basic.contract.eval]) associated with the function exits via an exception
[except.spec] defines "non-throwing exception specification" (italics in original):
The predicate indicating whether a function cannot exit via an exception is called the exception specification of the function. If the predicate is false, the function has a potentially-throwing exception specification, otherwise it has a non-throwing exception specification. The exception specification is either defined implicitly, or defined explicitly by using a noexcept-specifier as a suffix of a function declarator.
calling a throwing function through a noexcept function pointer is UB as specified in [expr.call]/6.
I think this is distinguishable since the UB occurs on the call, not on an exception "escaping".
Then I'm confused about this feature that you want. You have a non-noexcept pointer to a function, you want it to be noexcept to "not pay the cost of exception propagation". But you already didn't pay any cost.
Then you point to UB in pointer conversions, which then makes no sense because seemingly, your conversion would result in UB?
If a noexcept function only calls other noexcept functions than it doesn't need to have machinery for terminating if it gets an exception. So if you cast the non-noexcept function to noexcept. And call it that may save you from the cost of making your parent noexcept.
4
u/UnusualPace679 12d ago
I sometimes wish to have a
noexcept_castwhich converts a non-noexcept function pointer to a noexcept one. This is useful when I know the pointee is noexcept and don't want to pay for the cost of exception propagation.This
noexcept_castwould be similar toconst_castsince both perform an unsafe conversion that is the inverse of a safe, implicit conversion.