On Sun, May 29, 2022 at 3:49 PM Gavin Lambert via Boost < boost@lists.boost.org> wrote:
On 30/05/2022 02:10, Robert Ramey wrote:
On 5/28/22 3:39 PM, Andrzej Krzemienski wrote:
try {
lib::function(); } catch(lib::exception const&) { // handle failure }
Could you explain what's wrong with the above code?
I believe the point was that if exceptions are always caught immediately then it smacks of the "exceptions as control flow" anti-pattern, and a non-throwing form of the library function ought to be available/used instead. Essentially, the exception is being used as an alternative return value rather than as an actual exception.
It's from the school of thought that exceptions should be "truly exceptional" -- i.e. any condition that might theoretically raise an exception can be explicitly checked in advance by a non-throwing method
I'll let him speak for himself, but I'd be surprised if Andrzej's point comes from that school of thought, he is not a Rust programmer. :) The issue with such examples is that they are useless at best: an experienced programmer knows what to do, while a novice might think that he is always supposed to immediately catch exceptions, as may be the case in other languages (e.g. Java) which lack deterministic termination. The correct use of exception handling in C++ is to let exceptions propagate unmolested by default; there is no explicit checking for errors after calling a function that may throw. You catch only where the error can be handled and the program can restore normal operations. And while it is true that unhandled exceptions terminate the program, that is always a logic error, programs should handle all exceptions that may be thrown. Terminating the program when an exception is thrown is valid only under -fno-exceptions (in Boost you'd do that by providing a suitable definition for boost::throw_exception).