Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I’m not well versed in C++’s exception system, but why can’t the unwind system itself call std::terminate? Why does it need to be the annotated method (that unwinding returns to)?


Way more history than you asked for about how we got into this situation with noexcept:

Up to 2011:

https://akrzemi1.wordpress.com/2011/06/10/using-noexcept/

As of '17:

https://devblogs.microsoft.com/oldnewthing/20180928-00/?p=99...

(I think this is the final word; I don't see any changes to exceptions in high-level release notes for c++20 and c++23 -- did I miss anything?)


It doesn’t need to be, but the annotated function can still miss optimization opportunities, because it must be compiled as if it had a try-catch block if the compiler can’t prove the absence of exceptions, and this places constraints on reordering and inlining.

On the other hand, the guarantee given by noexcept can enable optimizations in the caller.


A try { } catch block that calls terminate has no overhead. Normally the constraints on reordering are because e.g. constructor/destructor semantics and other side effects need to be accurately preserved during unwinding, but here any exception is going to result on a call to terminate, and (auto) destructors are not going to run.

This was the entire point of noexcept versus the throw() specifier...


This is unfortunately not always true, even with a table-based unwinder. In order to detect the noexcept frame and call terminate(), the unwinder must be able to see the stack frame that has noexcept. This means that the compiler must suppress tail call optimization when a noexcept function tail calls a non-noexcept function.


It also needs an entry in the exception table, and more if the cold path is moved out of line. So at the very least there are code size issues.


Because the exception can’t be allowed to escape the function marked noexcept. No matter the actual implementation, the exception has to be effectively caught in that no except function.


Catching is a table lookup in modern systems. I've yet to see a measurable happy path slowdown caused by adding noexcept.


Well TFA explains one.

I also find it difficult to conceive of a case where adding noexcept would lead to slower/longer code, other than arbitrary noexcept overloads such as TFA.


The article describes the performance implications of the hash tables storing hashes. That it decides to do so based on examining noexcept() of passed in types doesn't make noexcept a pessimization itself


And, as you can see on the sibling thread where I'm being downvoted, there is an actual pessimization: since a noexcept function requires an eh_frame, it will not be able to tail-call (except for noexcept functions).


It can, and it does on decent runtimes.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: