Live data from Hacker News

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

16bpp.net

161–166 of 166 posts

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

#161
post #159

Earlier quoted context omitted.

Sure, but that's essentially the same as using explicit jumps through raw assembly instructions to go around C++'s destructor guarantees. That is, when your Java process runs non-Java code, of course this can defeat certain Java guarantees. No programming language can make promises for semantics of external code like this.

That's still the case in pure Java code. The "Class.newInstance()" method is a public method on the core Java API, calling "MyClass.class.newInstance()" is mostly equivalent to "new MyClass()". And the generics trick in the "sneaky throws" article I linked is also pure Java code, without any calls to "sun.misc.Unsafe".

Class.newInstance() is a known unsafe method and has been deprecated for quite some time now (since Java 9). It's similar to Haskell's unsafePerformIO from this point of view.

The generics hole is indeed interesting, but it's ultimately a known limitation of how generics were implemented in Java, the presence of type inference, and the design of the exception hierarchy, than an intentional feature. When inferring the type of T to apply in that example, there is no good unique solution: inferring T = Throwable would have been safer, but it makes many simple cases behave unexpectedly, especially with lambdas. Inferring T = RuntimeException is unexpected and unsafe, but in practice it makes many common cases be way more usable, so a call was made to do it, despite the hole.

C++'s templates wouldn't have a similar problem, as they actually instantiate the definition at compile time and can re-check it. Also, there is no equivalent issue to the ambiguous inference, because C++ doesn't do type inference of this kind at all, and anyway there is no problem of the exception hierarchy. Even if there were, C++ could also take the opposite choice than Java, and explicitly infer the safer option when both `noexcept` and `potentially-throws` were possible.

And of course Lombok is a tool for modifying the compilation of Java, so writing Lombok code is not exactly writing pure Java.

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

#162

Earlier quoted context omitted.

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

Things are much better in 2024 in MSVC than they were in 2014. The overhead today is mostly the additional metadata associated with tracking the state, and most of the inline compatibilities were worked through (with a ton of work by the compiler devs). So it's a binary size issue. We've even been working on that (I remember doing work to combine adjacent identical regions, etc). Not sure what the status is in GCC/LL…

Sounds promising!

Do you think optimizations could eventually bring the std::terminate version of noexcept near/up to par with a hypothetical UB noexcept, or do you think that at least some overhead will always be present?

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

#163

Earlier quoted context omitted.

No, calling throw in a noexcept function is a defined behavior (call std::terminate), and that behavior is not a diagnostic I think maybe WG21 was concerned a compiler engineer would be clever if throwing in noexcept were UB, for example and assume any block that throws is unreachable and could just be removed along with all blocks it postdominates. Compiler guys love optimizations that just remove code. The fastest…

Compilers are allowed to and do diagnose defined but undesirable behavior though, even more so if that's only enabled with an option.

Until yesterday I thought I was the only person in the world who thought the designed behavior was undesirable, though

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

#164
post #118

Earlier quoted context omitted.

> 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 exampl…

I am not sure I understand. You declare a win with no explanations or reasons. What is so beneficial in having different implementation of same functionality? Why source being available makes difference? We can ignore cases of optimized per platform implementations because std was not made for that. None of platforms that make sense to support now were available back when current ABI was set in stone.

> Why source being available makes difference?

Because the library is a spec, they don't have to be compatible at a binary level. This is obvious on a hardware architecture level (a 16-bit processor vs a 64-bit processor) but it's true even on the same hardware under the same OS (the different representations of std::string being a famous example). But they are all compatible at the API level -- which in C++ is the source level.

So this is why I mention compatibility at the source code level.

> What is so beneficial in having different implementation of same functionality? We can ignore cases of optimized per platform implementations because std was not made for that.

The point of having different implementations is that not every program has the same needs. The idea of a standard library is that it has a bunch of commonly-used functionality that you can just use so you can concentrate on your own program. You don't have to roll your own string class -- just use the standard one. You may later find you have special needs and need to roll your own, more restrictive string that does just what you want, but in most cases people won't have to. (You can argue whether the C++ standard library accomplishes this or not, but that's a separate matter).

A good example of this is std::map which was overspecified, and thus almost never what you want. If the specification had been looser than different implementations could have chosen different solutions, and even borrowed from each other.

And per-platform optimization is exactly part of std's requirements. Different implementations for the 16-bit and 64-bit cases is an easy to use example. The compilers output a lot of intrinsics to take advantage of CPU capabilities (a common example is memcpy, but there are many). Just try to read the source code for libc++ -- it's hard to read when you aren't familiar with it because it's 1 - full of corner cases so that it works with any code that uses it but also 2 - it's full of target-specific optimizations and special cases.

> None of platforms that make sense to support now were available back when current ABI was set in stone.

Well this is true, but since it's a spec it remains source-code compatible.

I don't know if your use of "ABI" was a typo for "API" or if you really meant "ABI". The APIs are set in stone because of back compatibility (like the notorious std::map example I call out above) but use of ABI, when used by the committee, refers to the de facto binary layout of code that's already been compiled. There are few platform ABI specifications for C++; they are mainly for C, with sometimes some Ada or FORTRAN calling convention stuff. Rarely do platforms say anything about C++, and when they do they don't specify much. There is also a little ABI requirement in C++ (e.g. address of a derived class must also be the address of its own most fundamental base class) but that's for something that is reflected at the source code level.

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

#165

Earlier quoted context omitted.

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.

sure but the unwind flags don’t prevent optimizations like exceptions

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

#166
post #164

Earlier quoted context omitted.

I am not sure I understand. You declare a win with no explanations or reasons. What is so beneficial in having different implementation of same functionality? Why source being available makes difference? We can ignore cases of optimized per platform implementations because std was not made for that. None of platforms that make sense to support now were available back when current ABI was set in stone.

> Why source being available makes difference? Because the library is a spec, they don't have to be compatible at a binary level. This is obvious on a hardware architecture level (a 16-bit processor vs a 64-bit processor) but it's true even on the same hardware under the same OS (the different representations of std::string being a famous example). But they are all compatible at the API level -- which in C++ is the s…

>> What is so beneficial in having different implementation of same functionality?

> The point of having different implementations is that not every program has the same needs.

Are we still chatting about porting exactly same game product to multiple platforms? Portable code means it performs exactly the same function in an app.

It is clear that we are talking past each other. I will leave you to it.

Post reply on HN