Live data from Hacker News

C++'s `noexcept` can sometimes help or hurt performance

16bpp.net

91–100 of 166 posts

Re: C++'s `noexcept` can sometimes help or hurt performance

#91
post #85

Earlier quoted context omitted.

Nah that was mostly about extern "C" functions which technically can't throw (so the noexcept runtime stuff would be optimized out) but in practice there is a ton of code marked extern "C" which throws

> in practice there is a ton of code marked extern "C" which throws Obviously, a random programmer could do any evil things, but does that apply to standard code, such as C standard library used from C++?

Yes, qsort and bsearch can throw.

Re: C++'s `noexcept` can sometimes help or hurt performance

#92
post #7

Earlier quoted context omitted.

No, noexcept confusingly doesn't mean "does not throw exceptions" in that sense. There is no constraint that says you can only call noexcept code from noexcept code - quite the opposite. Noexcept puts NO constraints on the code. All noexcept does is catch any exception and immediately std::terminate. Confusingly this means that noexcept should really be called deathexcept, since any exception thrown within kills the…

> All noexcept does is catch any exception and immediately std::terminate. I don't think this is a decent interpretation of what no except does. It misses the whole point of this feature, and confuses a failsafe with the point of using it. The whole point of noexcept is to tell the compiler that the function does not throw exceptions. This allows the compiler to apply optimizations, such as not needing to track down…

Except the compiler still needs to ensure that if an exception bubbles through a noexcept function, std::terminate will be called, even if the exception were caught at some level above. So it still needs to keep track of the noexcept frames, even when inlining the noexcept function.

Generally what a language feature is intended to do is less relevant than what it actually does, over time. Just like the "inline" keyword was intended as a compiler hint, but what it actually does is change the visibility of symbols across compilation units, and alter the rules for static variables.

Of course, noexcept isn't as useless as inline, yet. There are real uses of it as a hint in template metaprogramming, as you said.

Re: C++'s `noexcept` can sometimes help or hurt performance

#93
post #79

Earlier quoted context omitted.

Dude I am going to blow your mind

Eeeermm... I haven't heard an explosion, but 4+ hours has passed. Are you alive there, dude? Jokes aside - I'm always happy to be corrected, so please go on if I made a mistake somewhere.

You very likely can't always answer the question "will this function throw?", but it should be relatively easy to identify the subset of function that recursively call functions that are guaranteed not to throw. That's only a subset of all non-throwing functions of course.

Re: C++'s `noexcept` can sometimes help or hurt performance

#94
post #4

Shouldn't the compiler deduce noexcept for you?

The compiler can tell about the immediate function, but not any functions it calls. If a function marked noexcept calls a function that throws an exception, then the program is terminated with an uncaught exception. A called function can throw through a non-noexcept function to a higher-level exception handler no problem. So in order to avoid changing the semantics of the function, the compiler would have to be able…

> A called function can throw through a non-noexcept function to a higher-level exception handler no problem.

This is exactly the problem. To have made this a useful feature, it should have been more restrictive: a noexcept function should not have been allowed to call any function or operator or lambda that is not marked noexcept. Some extra syntax to allow function templates to be made "conditionally noexcept" would have been necessary, but overall the feature would have had a real use and real power to help make code safer, and more performant.

Java has the first part down, for the class of checked exceptions: a function that doesn't throw can't call functions that do (except in try/catch blocks, but that's largely irrelevant). The annoyances come because of the missing second part - the ability to make a generic function that throws for some type parameters, but doesn't for others.

Re: C++'s `noexcept` can sometimes help or hurt performance

#95
post #79

Earlier quoted context omitted.

Dude I am going to blow your mind

Eeeermm... I haven't heard an explosion, but 4+ hours has passed. Are you alive there, dude? Jokes aside - I'm always happy to be corrected, so please go on if I made a mistake somewhere.

I think their point was that the halting problem is NP hard, it is in fact undecidable. Since there is no algorithm that can solve it, there is no point in talking about complexity of that algorithm.

Alternatively, Java shows that it is very much possible to do this - the compiler can enforce that a function can't throw exceptions (limited to checked exceptions in Java, but that is besides the point). The way to do it is easy: just check that it doesn't call throw directly, and that all of the functions it calls are also marked noexcept. No need to explore things any deeper than that.

Of course, the designers of C++ didn't want to impose this restriction for various reasons.

Re: C++'s `noexcept` can sometimes help or hurt performance

#96

Oh man, don't get me started. This was a point in a talk I gave years ago called "Please Please Help the Compiler" (what I thought was a clever cut at the conventional wisdom at the time of "Don't Try to Help the Compiler") I work on MSVC backend. I argued pretty strenuously at the time that noexcept was costly and being marketed incorrectly. Perhaps the costs are worth it, but none the less there is a cost The reaso…

I’m curious: where does the overhead of try/catch come from in a “zero-overhead” implementation?

Is it just that it forces the stack to be “sufficiently unwindable” in a way that might make it hard to apply optimisations that significantly alter the structure of the CFG? I could see inlining and TCO being tricky perhaps?

Or does Windows use a different implementation? Not sure if it uses the Itanium ABI or something else.

Re: C++'s `noexcept` can sometimes help or hurt performance

#97
post #91
post #85

Earlier quoted context omitted.

> in practice there is a ton of code marked extern "C" which throws Obviously, a random programmer could do any evil things, but does that apply to standard code, such as C standard library used from C++?

Yes, qsort and bsearch can throw.

jfc... Can you give more info how did you learn this and to which lib implementation this applies?

Re: C++'s `noexcept` can sometimes help or hurt performance

#98
post #41

Earlier quoted context omitted.

You won't get a sense of how bad exceptions can be by using Godbolt. A lot of the magic of exceptions is handled behind the scenes by the compiler and/or the Itanium ABI. For example one disasterous consequence of using exceptions in GCC is that there is a global application wide lock used to manage stack unwinding. This means that only one single thread can unwind a stack at a time and the lock is held from the star…

> For example one disasterous consequence of using exceptions in GCC is that there is a global application wide lock used to manage stack unwinding. This might have been (partially?) fixed? GCC Bug 71744 "Concurrently throwing exceptions is not scalable" is marked "RESOLVED FIXED" [0], and commit 6e80a1d164d1 in particular looks interesting: > eliminate mutex in fast path of __register_frame > > > > This commit elimi…

It is great they finally found a solution, for a long time this was suspected to be unfixable without an ABI break.

Re: C++'s `noexcept` can sometimes help or hurt performance

#99

Earlier quoted context omitted.

> It's a compromised and goofy implementation with lots of warts. I don't think this case qualifies as an example. I think the only goofy detail in the story is expecting a random number generator to be non-random and deterministic with the only conceivable usecase being poorly designed and implemented test fxtures. > What's the point it in having a /standard/ library then? The point of standardized components is to…

> with the only conceivable usecase being poorly designed and implemented test fxtures. Reproducible pseudo-randomness is a necessity with fuzz testing. It is not a poor design approach when it is actually useful.

it is reproducible within a single standard library implementation, so usable for fuzz testing

Re: C++'s `noexcept` can sometimes help or hurt performance

#100
post #97
post #91

Earlier quoted context omitted.

Yes, qsort and bsearch can throw.

jfc... Can you give more info how did you learn this and to which lib implementation this applies?

Well, given that qsort and bsearch take a function pointer and call it, that function pointer can easily point to a function that throws. So I think this applies to all implementations of qsort and bsearch. Especially since there is no way to mark a function pointer as noexcept.
Post reply on HN