Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In C++, Is it possible to force the user to catch exceptions?

In short, is it possible to get C++ to force the invoker of a method to put a try...catch block?

(To clarify: I don't necessarily mean the immediate invoker, I mean forcing the fact that it's caught somewhere. Also, I'm talking about forcing at compile time.)

The long:

I've read that it not recommended to use exception specification and that it doesn't work properly anyway (http://4thmouse.com/mystuff/articles/UsingExceptionsEffectively.html)

But the general consensus seems to favor the use of exceptions to return errors over the user of writing methods that return error codes.

So if I'm writing say a library, what's to stop the user from calling my method without putting any try...catch blocks, and then getting his program crashing when my code throws an exception?

(To be clear, I only require the exception to be caught somewhere in the users stack, not necessarily in the immediate calling code, and the compiler to complain if this is not the case.)

like image 866
nappyfalcon Avatar asked Feb 09 '16 17:02

nappyfalcon


2 Answers

No, it is not.

Indeed, there is no mechanism to force the caller of a function (anywhere in the call stack) to handle any kind of error. At least, not via a compilation failure. Return values can be discarded. Even bundling error codes with return values (via expected<T, E>) doesn't issue a compile-time error if the user doesn't actually check to see if the value is available before fetching it.

C++17 may give us the [[nodiscard]] attribute, which allows compilers to issue a warning if a return value (presumably an error code) is discarded by the caller. But a compile-time warning will be as close as you can get.

like image 127
Nicol Bolas Avatar answered Oct 05 '22 02:10

Nicol Bolas


In short, is it possible to get C++ to force the invoker of a method to put a try...catch block?

No. This would defeat the whole purpose of exceptions. Exceptions are specifically made for the use case of propagating errors across multiple layers without the intermediate layers being aware of them.

Let's say you have a call hierarchy like A -> B -> C -> D -> E, and an error occurs in E. A can handle the error. B, C and D do not need to be aware of the error at all. This is exactly what exceptions are good for!

If you want to return an error directly to the caller because handling the error is indeed the caller's concern, then an exception is often the wrong design and a return value might be the better choice.


"Enforced" exceptions of a certain form have been tried in Java, but I'd consider it a failed experiment, as it usually results in code like this:

try {
    method();
} catch (SomeCheckedException ex) {
    // ignore
}

That C++ does not encourage this should be considered a feature.


I've read that it not recommended to use exception specification and that it doesn't work properly anyway

Exactly. The only exception specification which was ever useful and which worked was throw() to signal that no exception at all is thrown, and that one has been superseded in C++11 by noexcept.

But the general consensus seems to favor the use of exceptions to return errors over the user of writing methods that return error codes.

See above. It depends on whether you want an error to propagate or if the caller can and should handle it.

So if I'm writing say a library, what's to stop the user from calling my method without putting any try...catch blocks, and then getting his program crashing when my code throws an exception?

A library which requires its user to surround all function calls with try blocks has a bad interface and should be redesigned, accordingly.

Also... you assume that a "program" will use your library. But this assumption will not always be true. The library client may itself be a library. There may be a lot of different library layers between the program and your library. You use exceptions if you do not care which layer handles them.

like image 35
Christian Hackl Avatar answered Oct 05 '22 03:10

Christian Hackl