On Thu, Jun 15, 2017 at 12:17 PM, Ion GaztaƱaga via Boost < boost@lists.boost.org> wrote:
On 15/06/2017 0:54, Emil Dotchevski via Boost wrote:
If the exceptional path is not explicit, it is very easy to incorrectly
handle it or just to ignore that path. Just like strong types are safer, explicit paths are safer.
...and when it is not, you can use explicit path:
try { stuff } catch(...) { cleanup(); throw; }
Then there is no advantage of using exceptions.
In this case, the important thing is that there is no disadvantage of using exceptions when manual cleanup is needed. 99 times out of 100 it is not, and that's when exception handling shines.
, so better stick to errors which at least limit the types that must be handled, which usually reduces compiler-generated code (obviously the diagnostic is poorer, as you can't compare an int error return with a full class).
Yes, exception handling will use more static types, but the upside is type safety: when you catch an error, you know that such an error exists because otherwise you'll get a compile error. If instead you used int, and you check for error 42 instead of 43 there will be no compile error, and 43 may be an entirely invalid code. Of course you can easily avoid the types, by throwing and catching ints (or std::error_code), and checking their value dynamically, but then you're butchering type safety. I don't recommend it. If you didn't use exceptions, the above would look like this:
if( stuff_failed ) { cleanup(); return E_STUFF_FAILED; }
If all you need is "stuff_failed" then exceptions are better because you just want to cleanup and return. Exceptions do this automatically. Problems arise when you wan to handle all possible errors, do different things with each of them. And just make sure you correctly handle all errors.
Okay: try { stuff } catch( problem1 & ) { } catch( problem2 & ) { } catch( problem3 & ) { }
I find myself writing exception safe code, but rarely using them. And I rarely find programmers that properly understand how to use exceptions, whereas everybody understands a return type.
This is a fair point. If your team doesn't know how exception handling works you should not use it, use Noexcept instead. :)
std::filesystem needs to offer a dual interface for errors and exceptions. There is something missing here. And I don't have the answer.
The reason why filesystem needs dual interface is because for many operations it is impossible to define universal postconditions to be enforced by throwing exceptions: what in one use case is considered an error is not an error at all in some other case.