Live data from Hacker News

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

16bpp.net

111–120 of 166 posts

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

#111

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…

It's kinda funny that C++ even in recent editions generally reaches for the UB gun to enable optimizations, but somehow noexcept ended up to mean "well actually, try/catch std::terminate". I bet most C++-damaged people would expect throwing in a noexcept function to simply be UB and potentially blow their heap off or something instead of being neatly defined behavior with invisible overhead.

Unless you're C++-damaged enough to assume it's one of those bullshit gaslighting "it might actually not do anything lol" premature optimization keywords, like `constexpr`.

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

#112

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…

It's kinda funny that C++ even in recent editions generally reaches for the UB gun to enable optimizations, but somehow noexcept ended up to mean "well actually, try/catch std::terminate". I bet most C++-damaged people would expect throwing in a noexcept function to simply be UB and potentially blow their heap off or something instead of being neatly defined behavior with invisible overhead.

Probably the right thing for noexcept would be to enforce a "noexcept may only call noexcept methods", but that ship has sailed. I also understand that it would necessarily create the red/green method problem, but that's sort of unavoidable.

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

#113

Earlier quoted context omitted.

It's kinda funny that C++ even in recent editions generally reaches for the UB gun to enable optimizations, but somehow noexcept ended up to mean "well actually, try/catch std::terminate". I bet most C++-damaged people would expect throwing in a noexcept function to simply be UB and potentially blow their heap off or something instead of being neatly defined behavior with invisible overhead.

Unless you're C++-damaged enough to assume it's one of those bullshit gaslighting "it might actually not do anything lol" premature optimization keywords, like `constexpr`.

`inline` is my favorite example of this. It's a "This does things, not what you think it does, and also it's not used for what you think it is. Don't use it".

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

#114

Earlier quoted context omitted.

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" woul…

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

That's not actually true, it's possible to do "sneaky throws" (https://www.baeldung.com/java-sneaky-throws) of a checked exception from a method which isn't declared to throw that checked exception. The classic example is Class.newInstance(), which propagates any exception from the called constructor. Other ways are calling code from JVM languages other than Java, which do not have the same "checked exception" concept (like Kotlin: see https://kotlinlang.org/docs/exceptions.html and https://kotlinlang.org/docs/java-to-kotlin-interop.html#chec...), generics trickery to confuse the compiler, and manually creating JVM bytecode.

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

#115

Earlier quoted context omitted.

-fno-exceptions only prevents you from calling throw. If you don't want overhead likely you want -fno-asynchronous-unwind-tables + that clang flag that specifies that extern "C" functions don't throw

I'm pretty sure I could see a roughly 10% binary size decrease in my C++ projcts just by setting -fno-exceptions, and that was for C++ code that didn't use exceptions in the first place, so there must be more to it then just forbidding throw. Last time I tinkered with this stuff was around 2017 though.

You do not need unwind tables for noexcept functions, that can be a significant space saving.

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

#116

Earlier quoted context omitted.

> I argued then that if instead noexcept violations were undefined, we could ignore all this, and instead just treat it as the pure optimization it was being marketed as (ie, help prove a region can't throw, so we can elide entire try/catch blocks etc). Do you know if the reasoning for originally switching noexcept violations from UB to calling std::terminate was documented anywhere? The corresponding meeting minutes…

I think WG21 has been violently against adding additional UB to the language, because of some hacker news articles a decade ago about people being alarmed at null pointer checks being elided or things happening that didn’t match their expectation in signed int overflow or whatever. Generally it seems a view of spread that compiler implementers view undefined behavior as a license to party, that we’re generally having…

> I think WG21 has been violently against adding additional UB to the language, because of some hacker news articles a decade ago about people being alarmed at null pointer checks being elided or things happening that didn’t match their expectation in signed int overflow or whatever.

Huh, didn't expect the no-UB sentiment to have extended that far back!

> Regarding “not pan out”: I think the overhead of noexcept for the single function call case is fine, and inlining is and has always been the issue.

Do you know if the other major compilers also face similar issues?

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

#117
RE: unexpected performance degradation

programs can be quite sensitive to how code is laid out because of cache line alignment, cache conflicts etc.

So random changes can have a surprising impact.

There was a paper a couple of years ago explaining this and how to measure compiler optimizations more reliably. Sadly, I do not recall the title/author.

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

#118

Earlier quoted context omitted.

> as well as taking different implementation strategies (e.g. the small string optimization is different in libc++ and libstdc++ As a user this is really not a good thing when the stdlib is tied to the platform. In the end the only sane thing to do if you want any reproducibility across operating systems is to exclusively use libc++ everywhere.

>In the end the only sane thing to do if you want any reproducibility across operating systems is to exclusively use ... no std library code in portable code. FTFY. Ofc there are no absolutes. In gamedev essential type info bits and intrinsics are either allowed back or wrapped. Algorithm library is another bit allowed for the most part ( no unstable sort and such ). I know your approach of 'one ring-libc++ to rule t…

> no std library code in portable code. FTFY.

Just want to clarify what I think you meant: no std library code in portable binaries, something I agree with 100%.

If you distribute in source, I believe almost always the opposite is true: relying on the standard library is probably a win. Not every time: some complex code bases have nonstandard requirements or can benefit from nonstandard code. Gaming is a good example of this.

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

#119
post #51

Earlier quoted context omitted.

See my parallel reply: there are much more than just three, and all work with the three/four most dominant compilers these days as well as less dominant ones like EDG or Intel.

No, there are just 3 relevant standard implementations. There are numerous independent libraries that perform very similar but non-conformant functionality. My complaint is that the C++ standards committee should, when possible, release code and not a specification. They shouldn't release a std::map spec that 3 different vendors implement. The committee should write and release a single std::map implementation. It's…

> Rust's standard library is not a spec, it's just code.

I consider this profound weakness, not a strength.

Don’t get me wrong: I recognize the benefits in the short term! But really long lived languages like FORTRAN, Lisp, C++ have benefited hugely from a spec-based standards approach adopted from other engineering practice. They have also benefited from cross-fertilization from different implementations which influenced later standard and thus each other.

This is why standards from building codes to electrical systems, to ships, manufacturing QC sampling, TCP/IP (and all the internet RFCs) and basically the entire corpus of ISO standards are spec based.

If you want to build long-lived engineered systems it’s worth learning from people who figured out a lot of the metaprocesses the hard way, some of them for more than a century ago.

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

#120

Earlier quoted context omitted.

> I argued then that if instead noexcept violations were undefined, we could ignore all this, and instead just treat it as the pure optimization it was being marketed as (ie, help prove a region can't throw, so we can elide entire try/catch blocks etc). Do you know if the reasoning for originally switching noexcept violations from UB to calling std::terminate was documented anywhere? The corresponding meeting minutes…

I think WG21 has been violently against adding additional UB to the language, because of some hacker news articles a decade ago about people being alarmed at null pointer checks being elided or things happening that didn’t match their expectation in signed int overflow or whatever. Generally it seems a view of spread that compiler implementers view undefined behavior as a license to party, that we’re generally having…

Could the UB version of noexcept be provided as a compiler extension? Either a separate attribute or a compiler flag to switch the behavior would be fine.
Post reply on HN