Unexpected termination

A

Attila Feher

Hi all,

I have not done much work around exceptions; and even when I do I avoid
exception specifications. But now I have to teach people about these
language facilities, so I am trying them out with gcc 3.4.2-mingw.

I have tried the TCPL Spec.Ed. example of just adding std::bad_exception to
the exception specification of a function promising to throw an int, but
throwing a string-literal (effectively a pointer). I call that from main
inside a try bloc, with catching std::bad_exception after it. And yet, I
get terminate_handler being called, and gcc's verbose terminate handler
says:

"terminate called after throwing an instance of 'char const*'"

Now did I misunderstand Stroustrup? As I read the book if I add
std::bad_exception to the exception specification (and I also catch it) I
should not get terminate() called but I should have my char const* exception
be automagically translated into a std::bad_exception. Which does not
happen in my very simple code.

What did I miss? I am not waiting for gcc specific advice, I just would
like to know what the language should do. Although if someone knows for
sure that gcc (eh, g++) is faulty and let's me know, I won't be
disappointed. But I am mainly interested in the standard-mandated behavior.
If you could send a little code which works in your environment, I could
compare them...

I have the bad feeling I do something silly, but my code is so simple and I
see no place where it could be wrong. :-(

Do you see anything wrong? I must be something silly.

#include <iostream>
#include <exception>

void
liar_liar() throw(int,std::bad_exception) {
// Jim Carrey is not an int, but a character :)
throw "Jim Carrey";
}

//============================================

int main(int argc, char const *argv[]) {

// Forget this, just gives debugging aid
std::set_terminate(__gnu_cxx::__verbose_terminate_handler);

try {
liar_liar();
}
catch(char const *s) { ; }
catch(std::bad_exception &e) {
std::cout << "Bad exception caught: "
<< e.what() << std::endl;
}
}
 
K

Karthik Kumar

Attila said:
Hi all,

I have not done much work around exceptions; and even when I do I avoid
exception specifications. But now I have to teach people about these
language facilities, so I am trying them out with gcc 3.4.2-mingw.

I have tried the TCPL Spec.Ed. example of just adding std::bad_exception to
the exception specification of a function promising to throw an int, but
throwing a string-literal (effectively a pointer). I call that from main
inside a try bloc, with catching std::bad_exception after it. And yet, I
get terminate_handler being called, and gcc's verbose terminate handler
says:

"terminate called after throwing an instance of 'char const*'"

Now did I misunderstand Stroustrup? As I read the book if I add
std::bad_exception to the exception specification (and I also catch it) I
should not get terminate() called but I should have my char const* exception
be automagically translated into a std::bad_exception. Which does not
happen in my very simple code.

What did I miss? I am not waiting for gcc specific advice, I just would
like to know what the language should do. Although if someone knows for
sure that gcc (eh, g++) is faulty and let's me know, I won't be
disappointed. But I am mainly interested in the standard-mandated behavior.
If you could send a little code which works in your environment, I could
compare them...

I have the bad feeling I do something silly, but my code is so simple and I
see no place where it could be wrong. :-(

Do you see anything wrong? I must be something silly.

You need to use the 'unexpected' function handler here.

From the C++ specification -

Section 15.5.2


2) ... * If the exception-specification does not include the class
std::bad_exception (18.6.2.1) then the function terminate() is called,
otherwise the thrown exception is replaced by an implementation-defined
object of the type std::bad_exception and the search for another handler
will continue at the call of the function whose exception-specification
was violated **

3) Thus, an exception-specification guarantees that only the listed
exceptions will be thrown. If the exception-specification includes the
type std::bad_exception then any exception not on the list may be
replaced by std::bad_exception within the function unexpected().

Add an unexpected_handler as mentioned inline.
It should work fine.

There is no use in dealing with terminate_handler for these cases
since it is not supposed to return anyway.

#include <iostream>
#include <exception>

void
liar_liar() throw(int,std::bad_exception) {
// Jim Carrey is not an int, but a character :)
throw "Jim Carrey";
}

void unexpected_handler() {
throw 1.2;
}
//============================================

int main(int argc, char const *argv[]) {

// Forget this, just gives debugging aid
std::set_terminate(__gnu_cxx::__verbose_terminate_handler);

std::set_unexpected( unexpected_handler);
 
A

Attila Feher

Karthik said:
Attila Feher wrote: [SNIP]
Do you see anything wrong? I must be something silly.

You need to use the 'unexpected' function handler here.

From the C++ specification -

Section 15.5.2 [SNIP]
Add an unexpected_handler as mentioned inline.
It should work fine.

Yeah. The Stroustrup book is pretty vague on describing this. Reading the
standard makes it clear that one needs to define and set a custom unexpected
handler, but reading he text of The C++ Programming language at 14.6.3 gives
the impression that it is enough to add std::bad_exception.

Thanks for the section number of the standard. I still have difficulties
orienteering in those parts of it which I do not use regurarly.
There is no use in dealing with terminate_handler for these cases
since it is not supposed to return anyway.

Except (as it is mentioned clearly in the posted code) that the given
terminate handler *tells* why the terminate was called, do it had a very
important use for me.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,813
Latest member
lawrwtwinkle111

Latest Threads

Top