SomethingSomething
SomethingSomething

Reputation: 12176

C++/GCC: How to detect unhandled exceptions in compile time

Introduction: In Java, if you do not catch an exception, your code doesn't even compile, and the compiler crashes on unhandled exception.

Question: Is there a way to tell GCC to be "strict" as Java in this case, and to raise an error or at least a warning on unhandled exception?

If not - are there IDEs (for Unix, please) that can highlight such cases as a warning?

Upvotes: 4

Views: 2630

Answers (4)

James Kanze
James Kanze

Reputation: 153919

First, your statement concerning Java is false; only certain types of exceptions prevent the code from compiling. And for the most part, those types of exceptions correspond to things that are better handled by return codes. Exceptions are normally only an appropriate solution when propagating an error through a large number of functions, and you don't want to have to add exception specifications for all of those functions.

That's really why Java makes its distinctions: exceptions that derive from java.lang.Error should usually be crashes (assertion failures and the like in C++); and exceptions that derive from java.lang.RuntimeException should be exceptions in C++. Neither are checked in Java, either, because it isn't reasonable to have every function declare that it might throw one of them.

As for the rest, the exceptions which you want to catch immediately in the calling code, they are generally best handled by return codes, rather than exceptions; Java may use exceptions here because it has no out arguments, which can make using return codes more awkward. Of course, in C++, you can also silently ignore return codes, which is a drawback (but historical reasons, etc.). But the real issue is the contract, which is far more complex than function f might throw/return x; it's more along the lines of "function f will throw/return x, if condition c is met". And I know of no language which has a means of enforcing that. In C++ (and for checked exceptions in Java), exception specifications are more along the lines of "function f will not throw anything but x". Which is generally not very useful, unless "x" means all exceptions. In order to write really robust code, you need a few functions which are guaranteed never to throw. Interestingly enough, you can specify this in C++, both pre-C++11 (throw()) and post (noexcept); you cannot in Java, because you can't specify that a function won't throw a java.lang.RuntimeError.

(Or a java.lang.Error, but that's less of an issue, since if you get one of those, you're application is hosed anyway. Just how are you expected to recover from java.lang.VirtualMachineError? And of course, you can't really expect to be able to recover from a segment violation in C++ either. Although... java.lang.OutOfMemoryError derives from java.lang.VirtualMachineError; although not easy, and not always applicable, I've written C++ code which successfully recovered from std::bad_alloc.)

Upvotes: 0

n. m. could be an AI
n. m. could be an AI

Reputation: 119877

It is not possible in C++. Exception specification is a part of a function declaration but not a part of its type. Any indirect call (via pointer or virtual call) just completely wipes any information about exceptions.

Exception specifications are deprecated anyway in C++11 in favour of noexcept, so it is unlikely any compiler would bother to enhance this language feature.

Upvotes: 2

Mats Petersson
Mats Petersson

Reputation: 129374

You can ALWAYS use:

int main()
{
   try {
      ... your usual main ... 
   }
   catch(...)
   {
       std::cerr << "Unhandled exception caught" << std::endl;
   }
}

However, that is a fairly poor solution.

Unfortunately, the nature of C++ makes it very hard to catch the situation where something throws an exception and it's not handled, since just about everything has the potential to throw exceptions. I can only think of code-review - perhaps code analyzing tools, such as that built around CLANG will have the capability of doing this, but it probably won't be 100% accurate. In fact, I'm not even sure that the Clang Analyzer fully understands throw/try/catch currently, as it seems to not catch some fairly fundamental errors http://clang-analyzer.llvm.org/potential_checkers.html (see the "exceptions" heading).

Upvotes: 0

user1804599
user1804599

Reputation:

The only guarantee you can put on a C++ function is that it never throws an exception at all:

void f() noexcept;

However, this will terminate the program at runtime when an exception is thrown. It's not verified at compile-time.

If you want to guarantee that an error is handled, the closest you can get is returning a value of a type that wraps boost::variant<OK, Error> with a member function that takes two callbacks: a callback for the OK case and one for the Error case.

Upvotes: 0

Related Questions