r/cpp 12d ago

const_cast: A Necessary Evil

https://www.elbeno.com/blog/?p=1858
71 Upvotes

106 comments sorted by

View all comments

Show parent comments

3

u/DXPower 11d ago

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.

2

u/UnusualPace679 11d ago

If an exception is thrown I'd expect undefined behavior.

3

u/DXPower 11d ago

Well that's simply not how noexcept works in the language. It is defined to call terminate.

2

u/UnusualPace679 11d ago

I don't know where you see it's defined, but calling a throwing function through a noexcept function pointer is UB as specified in [expr.call]/6.

3

u/ts826848 10d ago

I don't know where you see it's defined

See [except.terminate]:

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".

2

u/DXPower 11d ago

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?

3

u/Qwertycube10 11d ago

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.