 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Guest
|
Posted: Thu Dec 07, 2006 1:26 am Post subject: use exception in default catch(...) |
|
|
In a default catch(...), I'd like to be able to look at the exception
that was caught, or somehow see what was thrown.
This would be immensely useful, for instance, in some sort of exception
handler one might have in main(), for instance.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Chris Uzdavinis Guest
|
Posted: Thu Dec 07, 2006 10:10 am Post subject: Re: use exception in default catch(...) |
|
|
josephgarry (AT) gmail (DOT) com wrote:
| Quote: | In a default catch(...), I'd like to be able to look at the exception
that was caught, or somehow see what was thrown.
This would be immensely useful, for instance, in some sort of exception
handler one might have in main(), for instance.
|
When you enter a default catch block, you have given up type
information. If you may be able to guess what type the exception is,
then you should add another exception handler that catches that type of
exception and not depend on the default handler being able to do
anything very specific.
Because nearly anything can be an exception object, from an int to a
member function pointer to a class derived from std::exception, inside
the catch(...) there is no interface you can use that could possibly
work on every type of exception. Thus, you cannot directly access the
exception object at all and cannot query it for any information. You
may rethrow it, or cleanup knowing that "an exception" has been thrown,
and it didn't match any of the types you tried to catch earlier.
(Note: you MAY call another function that re-throws the exception
inside a try-catch block that has a very long list of exception
handlers, perhaps for all known types (or categories of known types)
used for exceptions. By doing this you may use that function to try to
determine what the actual exception it is, though it does require you
to know and list out all the types in advance. If some unique new type
is thrown, there is no possible way to catch it except in the default
handler, and then you still don't know what type it actually is.
I think the best you can do is have a an exception base class (perhaps
even std::exception will be sufficient) and stick to that interface for
all exceptions. If you only throw objects that are in that hierarchy
type, you can catch the base class and it will catch everything you
throw. Then you'll only enter the default handler if you get a truly
unknown exception object.
Chris
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Randy Guest
|
Posted: Fri Dec 08, 2006 10:10 am Post subject: Re: use exception in default catch(...) |
|
|
{ Quoted signature removed. -mod }
James Kanze wrote:
| Quote: | josephgarry (AT) gmail (DOT) com wrote:
In a default catch(...), I'd like to be able to look at the exception
that was caught, or somehow see what was thrown.
This would be immensely useful, for instance, in some sort of exception
handler one might have in main(), for instance.
It's also essential in multi-threaded code, in order to
propagate an unknown exception type accross a join. I believe
that the issue is being currently addressed in this context in
the committee. It's still rather vague (in my mind, at least),
but the committee is aware of the problem, and giving it some
consideration. (That doesn't mean that there will be an
absolute solution. The committee could well decide that only
certain types of exceptions can be propagated. But given that
the compiler has this information somewhere, consideration is
being given to making it available to the user.)
|
But, why would you want to propagate an exception out of the thread in
which it occured? And what would that even mean?
Since each thread has its own stack, and exception propagation unwinds
the stack, does that not mean that propagating the exception beyond the
thread in which it occurred would be unwinding beyond the top of that
thread's stack? Is that desirable, or even possible?
Seems to me that if an exception in a thread reaches the top of that
thread's stack that should be the same as an unhandled exception trying
to percolate out of main(), and should be handled exactly the same way.
Randy.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
James Kanze Guest
|
Posted: Sat Dec 09, 2006 3:51 am Post subject: Re: use exception in default catch(...) |
|
|
Randy wrote:
| Quote: | James Kanze wrote:
josephgarry (AT) gmail (DOT) com wrote:
In a default catch(...), I'd like to be able to look at the exception
that was caught, or somehow see what was thrown.
This would be immensely useful, for instance, in some sort of exception
handler one might have in main(), for instance.
It's also essential in multi-threaded code, in order to
propagate an unknown exception type accross a join. I believe
that the issue is being currently addressed in this context in
the committee. It's still rather vague (in my mind, at least),
but the committee is aware of the problem, and giving it some
consideration. (That doesn't mean that there will be an
absolute solution. The committee could well decide that only
certain types of exceptions can be propagated. But given that
the compiler has this information somewhere, consideration is
being given to making it available to the user.)
But, why would you want to propagate an exception out of the thread in
which it occured?
|
Who knows? It depends on the application. I'd say that most of
the time, it doesn't make sense. But that "most of the time" is
based on my personal experience, and there are some important
programming domains where I've no experience.
| Quote: | And what would that even mean?
Since each thread has its own stack, and exception propagation unwinds
the stack, does that not mean that propagating the exception beyond the
thread in which it occurred would be unwinding beyond the top of that
thread's stack? Is that desirable, or even possible?
|
You're thinking too much at an implementation level. Exceptions
are a mechanism for reporting errors. Surely you wouldn't
claim that there is never a reason for an error report to
transit thread boundaries.
| Quote: | Seems to me that if an exception in a thread reaches the top of that
thread's stack that should be the same as an unhandled exception trying
to percolate out of main(), and should be handled exactly the same way.
|
At the language level, I agree. The problem is that as it
currently stands, the user has no means of capturing the error,
encapsulating it, and reporting it back to the joining thread.
What we'd like is that the user could somehow write low-level
thread handling code (which knows nothing of the types of
exceptions it might encounter) which does something like:
in the thread:
try {
// call the high level stuff...
} catch ( ... ) {
// package the exception and return it
// back through the join...
}
// package the normal return value and return it back
// through the join
and in the joining thread:
myThread.join() ;
// Test whether there was a returned exception.
// If so, unpackage it and throw it...
// Get the packaged return value, unpackage it,
// and return it.
I don't have any such use cases in my application domains, but
others apparently do, and the request to be able to do this
sounds reasonable to me.
The problem is, how do you repackage something without knowing
either its type or its value. Within the catch block, the
compiler does have this information, somewhere, and it doesn't
seem unreasonable to me to add global functions to the library
which would return the type, or return a void* to the cloned
value, or maybe which would return an extended object which
contained a pointer to the cloned value, and had a function to
throw the cloned value as an exception. Or something along
those lines.
Not that I think it essential. I could also accept the idea
that only specific types of exceptions could be propagated, say
those which derive from std::exception. If that were the case,
it would be sufficient for std::exception to support virtual
functions to clone the object and to raise an exception of the
most derived type. In which case, the above code becomes:
returnValueSlot = NULL ;
exceptionSlot = NULL ;
try {
// call the high level stuff...
returnValueSlot = returnValue ;
} catch ( std::exception const& error ) {
exceptionSlot = error.clone() ;
}
....
myThread.join() ;
if ( exceptionSlot != NULL ) {
exceptionSlot->raise() ;
}
return *returnValueSlot ;
(There are object lifetime issues here, which are difficult to
solve without garbage collection.)
--
James Kanze (GABI Software) email:james.kanze (AT) gmail (DOT) com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Pete Becker Guest
|
Posted: Sat Dec 09, 2006 3:52 am Post subject: Re: use exception in default catch(...) |
|
|
Randy wrote:
| Quote: |
Seems to me that if an exception in a thread reaches the top of that
thread's stack that should be the same as an unhandled exception trying
to percolate out of main(), and should be handled exactly the same way.
|
And what is that? Terminate the application? Pretty drastic. Maybe
terminate the thread. But propogation out of the thread doesn't
necessarily mean immediate propogation, which everyone pretty much
agrees won't fly. What's under consideration is save and rethrow,
essentially, so that when you ask for the thread's result you either get
a value that it computed or you get a rethrow of the exception that it
threw.
--
-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Al Guest
|
Posted: Sun Dec 10, 2006 9:26 am Post subject: Re: use exception in default catch(...) |
|
|
Hi,
Seungbeom Kim wrote:
| Quote: | Al wrote:
dasjotre wrote:
If you don't know what you'll catch, how could you know what to do with
it.
and if you don't know what to do with it, why would you catch it at all?
This isn't quite right. You wouldn't need to know what it was to be able
to use it. The behavior would be polymorphic. For instance, if the
syntax allowed something like a templated catch, instead of catch(...),
you could do something like:
try {
doSomething();
}
template <typename T
catch(const T& e) {
cerr << "Exception: " << e << endl;
log<T>(e);
}
This is impossible. Exceptions are a run-time mechanism, while templates
are a compile-time mechanism, so they don't mix. How could the compiler
figure out what kind of exceptions would be thrown by doSomething() and
generate different catch blocks for different types?
|
Assuming all the source is available, the compiler has all the
information it needs to figure out which exception types can bubble to a
given try-catch block, I believe.
Also, what I illustrated is just an example. I used template-like syntax
because it is familiar, but any syntax really would be fine
(compile-time or runtime).
| Quote: | Right now you have to use a whole stack of catch's to achieve a similar
(but incomplete) effect, and it is much more verbose. Languages like C#
or Java don't need this because everything that can be thrown has a
common base. Since C++ doesn't have that, it should allow better catch
support.
So, what does the common base support? Doesn't std::exception do a
similar thing? (Or you could define your own common base, of course.)
Not that you can prevent an int or a const char* being thrown, but I
don't expect any decent code to throw anything other than a descendant
of std::exception. (And if /you/ do it yourself, you know what types can
possibly be thrown...)
|
Well, I wouldn't expect decent code to do it, but it might, and I've
seen it happen. It would be a lot more convenient to have the compiler
help you with this.
In C#, the Exception class is very much like std::exception, but more
powerful. Everything that is thrown must derive from it, so:
catch (Exception e) {}
Catches everything (threadwise). In addition, an Exception object
carries very useful things like a message string, a detailed stack
trace, the source of the exception, an optional sub-exception if you
want to chain exceptions (this could be useful for throwing destructors,
I think), etc.
I never understood why C++ allows you to throw an int, or even a
pointer, for instance. What's /that/ about?
Cheers,
-Al.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
James Kanze Guest
|
Posted: Mon Dec 11, 2006 5:08 am Post subject: Re: use exception in default catch(...) |
|
|
Pete Becker wrote:
| Quote: | Randy wrote:
Seems to me that if an exception in a thread reaches the top of that
thread's stack that should be the same as an unhandled exception trying
to percolate out of main(), and should be handled exactly the same way.
And what is that? Terminate the application? Pretty drastic.
|
But probably appropriate for many applications. If the
exception percolates to the top of the thread, it is an error in
the program.
IMHO, there are really two separate issues: what happens by
default (and I could accept pretty much anything, although I'd
prefer it not be undefined behavior), and what the programmer
can do, provided he's willing to write the code to do it. The
current situation is that one cannot propagate an unknown
exception type over a join. This causes me absolutely no
problem in my current applications, but I'm pretty sure that
it's something that could be useful or desirable in certain
cases.
| Quote: | Maybe
terminate the thread.
|
Just silently terminating a thread is IMHO not an option, at
least not at the user level.
| Quote: | But propogation out of the thread doesn't
necessarily mean immediate propogation, which everyone pretty much
agrees won't fly. What's under consideration is save and rethrow,
essentially, so that when you ask for the thread's result you either get
a value that it computed or you get a rethrow of the exception that it
threw.
|
And, presumably, under user control---I don't get unless I ask
for it. (Of course, in a certain sense, it's automatically
under user control, since I can wrap my top level function in a
try block, and do whatever I want with the exception.)
Also, it leaves open the question of what happens with a
detached thread.
--
James Kanze (Gabi Software) email: james.kanze (AT) gmail (DOT) com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Alf P. Steinbach Guest
|
Posted: Mon Dec 11, 2006 6:15 am Post subject: Re: use exception in default catch(...) |
|
|
* Al:
| Quote: |
I never understood why C++ allows you to throw an int, or even a
pointer, for instance. What's /that/ about?
|
People who don't like ints or pointers have the freedom to just throw
them away.
Thus, we can conclude that the folks who made Lotus Notes really
disliked ints.
And the folks who made MFC really disliked pointers.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|