Live data from Hacker News

Current hardware trends make C++ exceptions harder to justify

open-std.org

1–10 of 516 posts

Re: Current hardware trends make C++ exceptions harder to justify

#3
> Root cause

> Traditional C++ exceptions have two main problems:

> 1) the exceptions are allocated in dynamic memory because of inheritance and because of non-local constructs like std::current_exception. This prevents basic optimizations like transforming a throw into a goto, because other parts of the program should be able to see that dynamically allocated exception object. And it causes problems with throwing exceptions in out-of-memory situations.

> 2) exception unwinding is effectively single-threaded, because the table driven unwinder logic used by modern C++ compilers grabs a global mutex to protect the tables from concurrent changes. This has disastrous consequences for high core counts and makes exceptions nearly unusable on such machines.

That's really interesting. I've become very anti-exceptions in recent years far various much-discussed reasons (eg hard to follow, false economy, difficult if not impossible to write threadsafe C++ code in particular, use of exceptions as flow control is an anti-pattern).

One of the porposals is a value-or-error type object, which is basically what Rust has. I really like Rust's enums and match expressions.

It seems so difficult to make changes like this to C++ at this point, at what point do you just have to start again?

Re: Current hardware trends make C++ exceptions harder to justify

#4
Wouldn’t changing the global mutex into a read/write be a simple way to fix things? Shared libraries changing the exception table at the same time as exceptions being thrown seems rare. Might also be fixable in an API-preserving way…

Edit: nope. This idea is discussed later in the paper (not fully ruled out but the answer may still require ABI changes for more subtle reasons)

Re: Current hardware trends make C++ exceptions harder to justify

#6
post #3

> Root cause > Traditional C++ exceptions have two main problems: > 1) the exceptions are allocated in dynamic memory because of inheritance and because of non-local constructs like std::current_exception. This prevents basic optimizations like transforming a throw into a goto, because other parts of the program should be able to see that dynamically allocated exception object. And it causes problems with throwing ex…

std::expected doesn't require language changes, it's a library type. If anything it shows how C++ is multi-paradigm

Re: Current hardware trends make C++ exceptions harder to justify

#7
post #3

> Root cause > Traditional C++ exceptions have two main problems: > 1) the exceptions are allocated in dynamic memory because of inheritance and because of non-local constructs like std::current_exception. This prevents basic optimizations like transforming a throw into a goto, because other parts of the program should be able to see that dynamically allocated exception object. And it causes problems with throwing ex…

I've been using `expected`, i.e. value-or-error type, for a while in C++ and it works just fine, but the article shows it has some noticeable overhead for the `fib` workload for instance. Not sure if the Rust implementation has a different design to make it perform better though.

Re: Current hardware trends make C++ exceptions harder to justify

#9
post #3

> Root cause > Traditional C++ exceptions have two main problems: > 1) the exceptions are allocated in dynamic memory because of inheritance and because of non-local constructs like std::current_exception. This prevents basic optimizations like transforming a throw into a goto, because other parts of the program should be able to see that dynamically allocated exception object. And it causes problems with throwing ex…

You don't have to start over with the whole language. Just use -fno-exceptions in your project and dictate the use of std::optional, or absl::StatusOr, or whatever your favorite variant return type may be. For the examples in the article, it may be perfectly fine to not support failure, to simply std::abort whenever the sqrt of a non-positive is requested and rename the function sqrt_or_die.

Re: Current hardware trends make C++ exceptions harder to justify

#10
> Nevertheless the overhead is so high that std::expected is not a good general purpose replacement for traditional exceptions.

This is basically the path Rust has chosen. I’m curious if it’s _actually_ too slow for C++. I feel like the answer must be no.

Post reply on HN