On Wed, May 24, 2017 at 2:30 PM, Niall Douglas via Boost < boost@lists.boost.org> wrote:
This may be true but your reasoning is still rather abstract. Does anyone have a concrete program where reporting a failure by throwing would be too expensive? If not, what problem are we aiming to solve with Outcome?
c.f. the AFIO v1 review some years ago where my view that the cost of throwing an exception was irrelevant compared to a disc i/o. I was still panned for that design choice.
This is presented as a matter of opinion. I was looking for something more objective, since I am familiar with the unsubstantiated "exceptions are slow!!!!" attitude (my background is in video game engines and no, there are no performance problems with throwing exceptions to report errors in games, despite what others claim without evidence.)
By the way, it would be very helpful if the examples in Outcome don't talk about failures to open files, especially if the objection to using exceptions is that their performance is "unpredictable".
File i/o failure can be both common and unpredictable. It's why AFIO v2 needed a very low overhead failure handling mechanism, and I use it with a vengeance in afio::algorithm::* the AFIO v2 filesystem algorithms library. Performance, especially on NVMe SSDs, is spectacular.
Spectacular, compared to what? Is it spectacular because it avoids throwing exceptions? When I mention the unpredictability of file operations, what I mean is that their performance is even _more_ unpredictable than the overhead of (the work done during) stack frame unwinding. It is wrong to be concerned with the unpredictability the performance of a throw in the case you're dealing with I/O.
I agree that talking about actual compilers today is relevant and should be considered, so when I'm discussing exception handling overhead I do mean actual real world uses.
In real world code, the cost of the exception throw and catch mechanism will be dwarfed by work done during the unwind in most cases. So for the average case, just go with C++ exceptions and relax.
But for some users, every possible execution path needs to have a hand allocated CPU cycle budget. For these users, Expected or Outcome is less error prone than integer error codes.
I'm still looking for these use cases. I keep hearing they exist, I am sure they exist, and it would be very helpful if Outcome lists a few of them and shows how throwing exceptions fails spectacularly in these cases, rather than talking about I/O, in which case you seem to agree it's better to throw exceptions to report failures.
abstractly, even not considering specific ABIs. After all, we don't talk about the overhead of using for loops vs. do-while, do we? It should be
That said, in the spirit of C++ we should think of exception handling the
same with exceptions. If I have:
try { throw x(); } catch( x & ) { }
there is no reason for any exception to be actually thrown. In principle, compilers should be able to see that the above is noop.
Most of the time trivially obvious try...catch are turned into a branch to early exit by the compiler. But it's not consistent. I've seen very obvious trivial try...catch get turned into a full dive into the runtime for execution despite the obviously inlined code. I would assume an optimiser bug.
The other possibility is ABI restriction. Either way, not a problem for the C++ definition itself.
From this point of view, there should be no performance difference between returning an error code or throwing an exception, and if there is, that is a problem of the compiler or the ABI but not of the semantics of exception handling as defined by C++.
For some users, "should" isn't enough. They want *guaranteed*.
It is not possible to guarantee that the optimizer will do a good job optimizing a for loop either, that's why I said "should". If your point is that it's more likely for a code generator to deal efficiently with a for loop than with throw..catch, that is probably true, but I didn't think that Outcome is designed as a workaround for the deficiencies of existing optimizers. Maybe all this means is that Outcome needs better examples, but I still don't understand its motivation. Or maybe it's as simple as "some people religiously avoid throwing exceptions and this is better than what they would do otherwise" Emil