Live data from Hacker News

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

16bpp.net

11–20 of 166 posts

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

#11
post #4

Shouldn't the compiler deduce noexcept for you?

No, it can't do that. My speculation is that likely it is so because in general case this might be a NP hard problem similar to the halting problem https://en.wikipedia.org/wiki/Halting_problem.

The best it can do is to say whether a given function is qualified with `noexcept` (see noexcept() operator https://en.cppreference.com/w/cpp/language/noexcept)

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

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

Oh, so it's like Rust's panic=abort

Panic=abort is more like -fno-exceptions since it applies to all the code being compiled and not just function. Codegen can also take advantage of the fact that it won't have to unwind.

I don't think there is a rust equivalent of noexcept.

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

#14
post #7
post #4

Shouldn't the compiler deduce noexcept for you?

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.

While that's a possible implementation; the standard is a bit more relaxed: `noexcept` may also call `std::terminate` immediately when an exception is thrown, without calling destructors in the usual way a catch block would do.

https://godbolt.org/z/YTe84M5vq test1 has a ~S() destructor call if maybe_throw() throws; test2 never calls ~S().

MSVC does not appear to support this optimization, so using `noexcept` with MSVC involves overhead similar to the catch-block.

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

#15
post #13

Earlier quoted context omitted.

Oh, so it's like Rust's panic=abort

Panic=abort is more like -fno-exceptions since it applies to all the code being compiled and not just function. Codegen can also take advantage of the fact that it won't have to unwind. I don't think there is a rust equivalent of noexcept.

Does C++ std::terminate unwind the stack and call destructors? Then noexcept would be pretty close to regular Rust panics, wouldn't it?

Basically an unrecoverable exception?

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

#16
post #2

> I didn't know std::uniform_int_distribution doesn't actually produce the same results on different compilers I think this is genuinely my biggest complaint about the C++ standard library. There are countless scenarios where you want deterministic random numbers (for testing if nothing else), so std's distributions are unusable. Fortunately you can just plug in Boost's implementation.

> There are countless scenarios where you want deterministic random numbers (for testing if nothing else), so std's distributions are unusable. Fortunately you can just plug in Boost's implementation.

I don't understand what's your complain. If you're already plugging in alternative implementations,what stops you from actually stubbing these random number generators with any realization at all?

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

#17
post #4

Shouldn't the compiler deduce noexcept for you?

A lot of people have answered no, which is likely the correct answer to what you're asking, but I wanted to be clear about exactly what that is?

Take a hypothetical piece of code

some_library_header.h:

    void library_function();
some_project_header_1.h:

    void project_function1();
some_project_header_2.h:

    void project_function2();

some_project_file.cpp:

    void project_function2() {
        /* definition */
        // no exception
    }

    void test_function1() {
        library_function();
    }

    void test_function2() {
        project_function1();
    }

    void test_function3() {
        project_function2();
    }

For your question, where are you wanting to know if the compiler can deduce noexcept?

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

#18
The most common place where noexcept improves performance is on move constructors and move assignments when moving is cheaper than copying. If your type is not nothrow moveable std::vector will copy it instead of moving when resizing, as the move constructor throwing would leave the vector in an invalid state (while the copy constructor throwing leaves the vector unchanged).

Platforms with setjmp-longjmp based exceptions benefit greatly from noexcept as there’s setup code required before calling functions which may throw. Those platforms are now mostly gone, though. Modern “zero cost” exceptions don’t execute a single instruction related to exception handling if no exceptions are thrown (hence the name), so there just isn’t much room for noexcept to be useful to the optimizer.

Outside of those two scenarios there isn’t any reason to expect noexcept to improve performance.

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

#19
post #2

> I didn't know std::uniform_int_distribution doesn't actually produce the same results on different compilers I think this is genuinely my biggest complaint about the C++ standard library. There are countless scenarios where you want deterministic random numbers (for testing if nothing else), so std's distributions are unusable. Fortunately you can just plug in Boost's implementation.

> There are countless scenarios where you want deterministic random numbers (for testing if nothing else), so std's distributions are unusable. Fortunately you can just plug in Boost's implementation. I don't understand what's your complain. If you're already plugging in alternative implementations,what stops you from actually stubbing these random number generators with any realization at all?

It's a compromised and goofy implementation with lots of warts. What's the point it in having a /standard/ library then?

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

#20
post #10

That's quite interesting and a huge work has been done here, respect for that. Here's what has jumped out at me: `noexcept` qualifier is not free in some cases, particularly, when a qualified function could actually throw, but is marked `noexcept`. In that case, a compiler still must set something up to fulfil the main `noexcept` promise - call `std::terminate()` if an exception is thrown. That means, that putting `n…

> then unfortunately it's totally invalid since it measures time with the `std::chrono::system_clock` which isn't monotonic. Given how long the code required to run, it's almost certain that the clock has been adjusted several times

monotonic clocks are mostly useful for short measurement periods. for long-term timing wall-time clocks (with their adjustments) are more accurate because they will drift less.

Post reply on HN