6

It is my understanding that all exceptions in c++ ultimately extend exception. In Java world, catching Exception e would have worked regardless of the type of Exception. How is this done in C++?

Why is that in this snippet exception is not caught?

try{        
    int z = 34/0;
    cout << "This line should not appear" << endl;
} catch (exception e) {
    cout << "An error has occurred: " << e.what();  // Not executed
}

Also, in C++, how can one find out what actions causes what exception?

James Leonard
  • 3,593
  • 5
  • 27
  • 32
  • http://stackoverflow.com/questions/315948/c-catching-all-exceptions – Mysticial Aug 29 '12 at 03:57
  • As an aside, when there are exceptions -- even ones derived from `std::exception` -- this still won't work properly. You need to catch a *reference* so that polymorphism happens properly: your code catches a *copy*, truncated down to the base class `exception`. –  Aug 29 '12 at 04:28

4 Answers4

6

Why is that in this snippet exception is not caught?

An integer divided by 0 is not a standard c++ exception. So no exception is thrown in this case what you get is an plain Undefined Behavior.

Some specific compilers might map this scenario to an particular exception and you will have to check your compiler documentation to find the same.However, using such a feature will be non-portable and your code will be restricted to your specific compiler.

The best you can do in such a scenario is to check the error condition(divisor equals zero) yourself and throw an exception explicitly.

Also, in C++, how can one find out what actions causes what exception?

The std::exception class provides a method std::exception::what() specifically for this.

Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • 1
    On a side note, will catching `exception` catch any other exceptions? – James Leonard Aug 29 '12 at 03:48
  • 3
    @JamesLeonard Only if those exceptions are sub-classes of `std::exception`. To catch *all exceptions*, just use `catch(...)`. See [here](http://stackoverflow.com/q/315948/478288). – chrisaycock Aug 29 '12 at 03:49
  • Right. Thank you. Same as with Java then. – James Leonard Aug 29 '12 at 03:50
  • 4
    @JamesLeonard: You should only check if something matches Java as curiosity. The two are different languages, so you should pretend you don't know Java while learning; any similarities are merely coincidence, and may even only seem similar on the surface. – GManNickG Aug 29 '12 at 03:52
  • 3
    @JamesLeonard: Also, note that using a catch-all `catch(...)` is usually a bad practice.It simply hides the errors in your program and you should avoid using it.Instead you should catch only specific exceptions and fix the errors that might cause unexpected exceptions to be thrown. – Alok Save Aug 29 '12 at 03:54
  • Right guys, the question is largely academic. Thank you again. – James Leonard Aug 29 '12 at 03:55
  • @JamesLeonard The syntax is not the same as Java, from what we could see from @chrisaycock's comment. In Java, it's `catch (Exception var)` where in C++ it's `catch (...)` – asgs Aug 29 '12 at 03:57
  • @asgs That is not true. In Java it is `catch (Throwable t)` - although ill advised. – Christian.K Aug 29 '12 at 04:07
  • @Christian.K Yes, we are talking about `Exception`s in specific, that's why `catch (Exception var)` is sufficient. – asgs Aug 29 '12 at 06:30
  • @asgs Fair enough. However, I thought the topic was (still) "catching _any_ exception". That does not imply that the "object" being thrown actually bears the word "exception" in its name. – Christian.K Aug 29 '12 at 07:20
2

Divide by 0 causes most CPUs to follow some kind of escalation procedure which may be called an exception, signal, interrupt, trap or whatever in that CPU manufacturer's jargon. None of these - even if the term "exception" is also used - have any direct relationship to C++ language exceptions.

In C++, because it's generally expensive in CPU cycles and object code size to test repeatedly for divide by zero, compiler generated code for the inbuilt types is not required to do any such checking. In practice, it's usually sufficient to trust that the programmer will code to avoid a divide by zero, inserting explicit checks in the subset of divisions where they're useful; factoring such checks to avoid redundancy.

If the programmer wants a consistent guaranteed check, they can create a User Defined Type (a class with custom overloaded operators) that can be used in place of an inbuilt numeric type, but takes the time to check for division by zero (or underflow, overflow or whatever other concerns the developer has) and reacts however the programmer likes. I gather that languages like JAVA and C# lack operator overloading, which I'd imagine means they can't painlessly replace an inbuilt type in this way, needing invasive code changes to explicitly call functions instead of using the intuitive mathematical operators.

Anyway, as the C++ Standard itself doesn't specify some behaviour for divide-by-zero situations, the implementation's free to provide some potentially useful behaviour if it chooses. That could imaginably include somehow generating an actual C++ language exception, but in practice it's likely to be too expensive in CPU cycles and code size to justify. Perhaps JAVA is so slow and bloated anyway that a little extra checking like this is neither here nor there...? ;-)

Say you're on a x86-family CPU, the term for a divide by 0 notification is "interrupt". But, if that machine's running say UNIX or Linux, the division results in a "signal" at the Operating System level, and you can set a signal handler to get notification of the problem.

Tony Delroy
  • 102,968
  • 15
  • 177
  • 252
1

You write

It is my understanding that all exceptions in c++ ultimately extend exception

That's wrong. A C++ exception can be of most any type. With C++98 it had to be copyable, but possibly (and most likely) that restriction has been lifted with C++11.

In Java world, catching Exception e would have worked regardless of the type of Exception. How is this done in C++?

By a catch-all clause,

    catch( ... )

The main problem with that is that if you want any information about the exception, then in C++98 you have to rethrow, which is not a particularly efficient way. And C++11’s exception handling facilities may not yet be supported by your toolchain, as of 2012.

Why is that in this snippet exception is not caught?

Because there is no C++ exception. Typically a compiler will simply refuse to compile the constant expression 34/0. I can't think of any compiler except g++ that would compile it: have you actually compiled that code?.

Anyway, if one manages to compile that code, then from a standard C++ point of view it simply results in Undefined Behavior, where anything and nothing can happen. If you’re lucky you’ll get a signal, but nothing’s guaranteed. It can however be possible to use platform-specific functionality to catch such events.

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
0

Divide-by-zero does not raise an exception in C++. See here, here, and here for example.

Community
  • 1
  • 1
chrisaycock
  • 36,470
  • 14
  • 88
  • 125