 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
White Wolf Guest
|
Posted: Mon Mar 07, 2005 11:18 am Post subject: std::bad_exception, sit, sit! |
|
|
Hi,
In 15.5.2/2 Simon says:
"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."
Clarification request:
The word "include" above may be understood two ways.
1.) One is, that the list (making up the exception specification) contains
the std::bad_exception itself, as the letter of std::bad_exception, or maybe
bad_exception, if a using directive or declaration associates that with
std::bad_exception.
2.) The other is, that the exception specification as a filter, applied,
does allow std::bad_exception to be thrown even, if that the type itself
does not appear in the exception specification.
We could argue for both of the above. I have tried it with g++, it goes
with the second meaning. What was/is the standards intent? Should a
compiler do the "conversion" into std::bad_exception even, if it is only
implicitly included in the specification? I mean if someone says: I want to
allow all exceptions inherited from std::exception that someone does not
necessarily want to say (as well) that "BTW, and change all other exceptions
a handler may throw to std::bad_exception for me".
So what was the intent here?
--
WW aka Attila
:::
Honesty is the best policy, but insanity is a better defence.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Roland Pibinger Guest
|
Posted: Mon Mar 07, 2005 11:24 pm Post subject: Re: std::bad_exception, sit, sit! |
|
|
On 7 Mar 2005 06:18:16 -0500, "White Wolf" <wolof (AT) freemail (DOT) hu> wrote:
| Quote: | In 15.5.2/2 Simon says:
"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."
Clarification request:
The word "include" above may be understood two ways.
1.) One is, that the list (making up the exception specification) contains
the std::bad_exception itself, as the letter of std::bad_exception, or maybe
bad_exception, if a using directive or declaration associates that with
std::bad_exception.
2.) The other is, that the exception specification as a filter, applied,
does allow std::bad_exception to be thrown even, if that the type itself
does not appear in the exception specification.
|
Good to see that someone cares about exception specifications.
IMO, it's 2.) Why should std::bad_exception be different from other
exception specifications?
| Quote: | We could argue for both of the above. I have tried it with g++, it goes
with the second meaning.
|
The last time I tried the following did not work on several older
compilers (but should according to the C++ Standard):
void foo () throw (std::exception) {
throw "nope";
}
| Quote: | What was/is the standards intent? Should a
compiler do the "conversion" into std::bad_exception even, if it is only
implicitly included in the specification?
|
Yes, hopefully!
| Quote: | I mean if someone says: I want to
allow all exceptions inherited from std::exception that someone does not
necessarily want to say (as well) that "BTW, and change all other exceptions
a handler may throw to std::bad_exception for me".
So what was the intent here?
|
Maybe something remotely similar to the distinction between checked
and unchecked exceptions in Java? e.g.
Connection* connect (Database& db) throw (DBException,std::exception);
DBException is an expected ("checked") exception, anything else is
not expected ("unchecked"). std::exception is specified since we don't
want to crash the program because of an unexpected exception.
Best regards,
Roland Pibinger
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
David Abrahams Guest
|
Posted: Tue Mar 08, 2005 11:03 am Post subject: Re: std::bad_exception, sit, sit! |
|
|
[email]rpbg123 (AT) yahoo (DOT) com[/email] (Roland Pibinger) writes:
| Quote: | 2.) The other is, that the exception specification as a filter, applied,
does allow std::bad_exception to be thrown even, if that the type itself
does not appear in the exception specification.
Good to see that someone cares about exception specifications.
IMO, it's 2.) Why should std::bad_exception be different from other
exception specifications?
|
It isn't. That's just the behavior of the default unexpected handler.
Substitute a different one if you don't like that behavior.
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
White Wolf Guest
|
Posted: Tue Mar 08, 2005 11:05 am Post subject: Re: std::bad_exception, sit, sit! |
|
|
Roland Pibinger wrote:
| Quote: | On 7 Mar 2005 06:18:16 -0500, "White Wolf" <wolof (AT) freemail (DOT) hu> wrote:
[SNIP]
The word "include" above may be understood two ways.
1.) One is, that the list (making up the exception specification)
contains the std::bad_exception itself, as the letter of
std::bad_exception, or maybe bad_exception, if a using directive or
declaration associates that with std::bad_exception.
2.) The other is, that the exception specification as a filter, applied,
does allow std::bad_exception to be thrown even, if that the type itself
does not appear in the exception specification.
Good to see that someone cares about exception specifications.
IMO, it's 2.) Why should std::bad_exception be different from other
exception specifications?
[SNIP] |
The rule of least surprise may apply here. I was not talking about "if the
unexpected-handler happens to throw an std::bad_exception", but I was
talking about a case when it attempts to throw an unexpected exception.
I think there is a clear distinction between asking for all exceptions
grouped under std::exception to be accepted to be thrown (a.k.a exception
specifications) and requesting an implicit conversion of toher exceptions to
be thrown! IMO it is a huge difference.
As for me caring for exceptions specifications... I have to be honest, I
don't. I have to teach them, so I want to know them properly. But they do
not capture my imagination until they will be checked compile time. What
they can do runtime (crashing my code/changing blindly one exception to
another) I can do more nicely by hand. I don't argue that there are good
reason for exception specification being what they are. Basically due to
the fact that existing code did not have exception specifications, it was
not possible to make them mandatory. It was probably also unclear (and
unimportant) at the time how to help templates to synthetize their
specifications. So in no way I am trying to blame anyone for anything, but:
My point of view, is that the current way these specifications work (except
probably for the no-throw one), checked compile time, there is an equal
chance that the exception specification is bad or the exception is bad.
That is (as I view it, I may be wrong) basically doubling the opportunity
for failure. At least in complex systems, where not all execution path can
really be tested in the lifetime of our universe.
--
WW aka Attila
:::
When the pupil is ready, the teacher will come.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Tue Mar 08, 2005 11:22 am Post subject: Re: std::bad_exception, sit, sit! |
|
|
Roland Pibinger wrote:
| Quote: | On 7 Mar 2005 06:18:16 -0500, "White Wolf"
wrote:
In 15.5.2/2 Simon says:
"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."
Clarification request:
The word "include" above may be understood two ways.
1.) One is, that the list (making up the exception
specification) contains the std::bad_exception itself, as the
letter of std::bad_exception, or maybe bad_exception, if a
using directive or declaration associates that with
std::bad_exception.
2.) The other is, that the exception specification as a
filter, applied, does allow std::bad_exception to be thrown
even, if that the type itself does not appear in the
exception specification.
Good to see that someone cares about exception specifications.
IMO, it's 2.) Why should std::bad_exception be different from
other exception specifications?
|
Because the standard says it is:-).
Seriously, there's a lot of history floating about exception
specifiers, and how to handle a mismatch. I think some early
specifications allowed bad_exception to propagate through a
throw(), for example. I don't think that anyone thinks that the
current situation is perfect and elegant, but I doubt you could
get a concensus on what is perfect and elegant. As most people
can live with the current situation, it represents an acceptable
compromize.
| Quote: | We could argue for both of the above. I have tried it with
g++, it goes with the second meaning.
The last time I tried the following did not work on several
older compilers (but should according to the C++ Standard):
void foo () throw (std::exception) {
throw "nope";
}
|
What do you mean, did not work? According to the standard, it
should call unexpected(). Unless you've replaced this function,
it should call terminate. This is what it does with the two
compilers I use: Sun CC and g++. What happened with your
compilers?
| Quote: | What was/is the standards intent? Should a compiler do the
"conversion" into std::bad_exception even, if it is only
implicitly included in the specification?
Yes, hopefully!
|
I'm pretty sure that this was the intent.
| Quote: | I mean if someone says: I want to allow all exceptions
inherited from std::exception that someone does not
necessarily want to say (as well) that "BTW, and change all
other exceptions a handler may throw to std::bad_exception
for me".
So what was the intent here?
Maybe something remotely similar to the distinction between
checked and unchecked exceptions in Java? e.g.
Connection* connect (Database& db) throw
(DBException,std::exception); |
| Quote: | DBException is an expected ("checked") exception, anything
else is not expected ("unchecked"). std::exception is
specified since we don't want to crash the program because of
an unexpected exception.
|
Not really. The C++ exception handling mechanism doesn't map to
the Java one. They're different, especially here.
First of all, the C++ standard explicitly forbids static
checking; the function you wrote above won't compile under Java
(for several reasons, of course), but the C++ standard requires
it to compile, even though we know that the exception "nope"
cannot possibly propagate out of the function.
Second, Java imposes an exception hierarchy at the language
level; C++ allows you to throw anything. This has advantages
and disadvantages; I occasionally throw an int rather than
calling exit -- I catch it in main and return it, having called
all my intermediate destructors (which calling exit doesn't do).
On the other hand, the only way to be sure of catching
everything is a catch(...), and then there's no way to access
the exception, where as in Java, there's always catch
(Throwable). (On the other hand, the Java hierarchy is poorly
designed, since there is no way of saying you want to catch
everything but the RuntimeException.)
All in all, I rather prefer the way the C++ system works,
although I would prefer static checking, and bad_exception is
pretty much a wart. (Given Attila's comments, it would probably
have been better if it didn't derive from std::exception. But
in practice, I don't replace unexpected(), so bad_exception
never occurs, and I don't have to worry about it.
--
James Kanze GABI Software
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 |
|
 |
Roland Pibinger Guest
|
Posted: Wed Mar 09, 2005 10:58 am Post subject: Re: std::bad_exception, sit, sit! |
|
|
On 8 Mar 2005 06:22:38 -0500, [email]kanze (AT) gabi-soft (DOT) fr[/email] wrote:
| Quote: | Roland Pibinger wrote:
The last time I tried the following did not work on several
older compilers (but should according to the C++ Standard):
void foo () throw (std::exception) {
throw "nope";
}
What do you mean, did not work? According to the standard, it
should call unexpected(). Unless you've replaced this function,
it should call terminate.
|
Really? Note especially the "otherwise ...replaced ..." in the
Standard excerpt quoted above:
15.5.2 The unexpected() function
"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."
The question is: Do the following functions result the same behavior
because std::bad_exception is derived from std::exception? IMO, both
functions should throw an exception and should not call terminate:
void foo1() throw (std::exception) {
throw "nope";
}
void foo2() throw (std::bad_exception) {
throw "nope";
}
Best wishes,
Roland Pibinger
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
David Abrahams Guest
|
Posted: Wed Mar 09, 2005 11:22 pm Post subject: Re: std::bad_exception, sit, sit! |
|
|
[email]rpbg123 (AT) yahoo (DOT) com[/email] (Roland Pibinger) writes:
| Quote: | The question is: Do the following functions result the same behavior
because std::bad_exception is derived from std::exception? IMO, both
functions should throw an exception and should not call terminate:
void foo1() throw (std::exception) {
throw "nope";
}
void foo2() throw (std::bad_exception) {
throw "nope";
}
|
Unless you've replaced the unexpected handler, both functions call
terminate because char const[5] does not match either exception
specification. What exception would you have these functions throw,
and how would it be generated?
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Roland Pibinger Guest
|
Posted: Thu Mar 10, 2005 9:24 am Post subject: Re: std::bad_exception, sit, sit! |
|
|
On 9 Mar 2005 18:22:35 -0500, David Abrahams
<dave (AT) boost-consulting (DOT) com> wrote:
| Quote: | rpbg123 (AT) yahoo (DOT) com (Roland Pibinger) writes:
The question is: Do the following functions result the same behavior
because std::bad_exception is derived from std::exception? IMO, both
functions should throw an exception and should not call terminate:
void foo1() throw (std::exception) {
throw "nope";
}
void foo2() throw (std::bad_exception) {
throw "nope";
}
Unless you've replaced the unexpected handler, both functions call
terminate because char const[5] does not match either exception
specification. What exception would you have these functions throw,
and how would it be generated?
|
"... otherwise the thrown exception is replaced by an
implementation-defined object of the type std::bad_exception ...".
"is replaced" not "might be replaced". That's the purpose of the
std::bad_exception mechanism. foo2() should throw std::bad_exception
according to the Standard (see also description and example in TCPL
14.6.3). Whether foo1() should throw std::bad_exception (because
std::exception is a base class of std::bad_exception) is debatable.
Best regards,
Roland Pibinger
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
David Abrahams Guest
|
Posted: Thu Mar 10, 2005 8:29 pm Post subject: Re: std::bad_exception, sit, sit! |
|
|
[email]rpbg123 (AT) yahoo (DOT) com[/email] (Roland Pibinger) writes:
| Quote: | On 9 Mar 2005 18:22:35 -0500, David Abrahams
[email]dave (AT) boost-consulting (DOT) com[/email]> wrote:
[email]rpbg123 (AT) yahoo (DOT) com[/email] (Roland Pibinger) writes:
The question is: Do the following functions result the same behavior
because std::bad_exception is derived from std::exception? IMO, both
functions should throw an exception and should not call terminate:
void foo1() throw (std::exception) {
throw "nope";
}
void foo2() throw (std::bad_exception) {
throw "nope";
}
Unless you've replaced the unexpected handler, both functions call
terminate because char const[5] does not match either exception
specification. What exception would you have these functions throw,
and how would it be generated?
"... otherwise the thrown exception is replaced by an
implementation-defined object of the type std::bad_exception ...".
"is replaced" not "might be replaced".
|
Whoops, sorry, you're right.
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Ron Natalie Guest
|
Posted: Thu Mar 10, 2005 8:32 pm Post subject: Re: std::bad_exception, sit, sit! |
|
|
Roland Pibinger wrote:
| Quote: | Unless you've replaced the unexpected handler, both functions call
terminate because char const[5] does not match either exception
specification. What exception would you have these functions throw,
and how would it be generated?
"... otherwise the thrown exception is replaced by an
implementation-defined object of the type std::bad_exception ...".
"is replaced" not "might be replaced". That's the purpose of the
std::bad_exception mechanism. foo2() should throw std::bad_exception
according to the Standard (see also description and example in TCPL
14.6.3). Whether foo1() should throw std::bad_exception (because
std::exception is a base class of std::bad_exception) is debatable.
|
That clause refers to exceptions that unexpected throws/rethrows.
If you read 15.5.1, (a few lines up from where you're looking) you'll
see the last of the conditions that terminate() is called is for when
you have a exception specificadtion violation and the DEFAULT
unexpected() is called.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Roland Pibinger Guest
|
Posted: Fri Mar 11, 2005 11:27 am Post subject: Re: std::bad_exception, sit, sit! |
|
|
On 10 Mar 2005 15:32:01 -0500, Ron Natalie <ron (AT) sensor (DOT) com> wrote:
| Quote: | Roland Pibinger wrote:
Unless you've replaced the unexpected handler, both functions call
terminate because char const[5] does not match either exception
specification. What exception would you have these functions throw,
and how would it be generated?
"... otherwise the thrown exception is replaced by an
implementation-defined object of the type std::bad_exception ...".
"is replaced" not "might be replaced". That's the purpose of the
std::bad_exception mechanism. foo2() should throw std::bad_exception
according to the Standard (see also description and example in TCPL
14.6.3). Whether foo1() should throw std::bad_exception (because
std::exception is a base class of std::bad_exception) is debatable.
That clause refers to exceptions that unexpected throws/rethrows.
If you read 15.5.1, (a few lines up from where you're looking) you'll
see the last of the conditions that terminate() is called is for when
you have a exception specificadtion violation and the DEFAULT
unexpected() is called.
|
The wording is fuzzy and contradictory in this case. Stroustrup wites
on his homepage ( http://www.research.att.com/~bs/3rd_issues.html )
that the "draft standard doesn't support the mapping of exceptions as
I describe it in 14.6.3" ("draft standard"!!) and "I have raised the
issue in the standards committee." No result of this effort is given.
This may be a defect in the standard that nobody cares to address.
Thank you for the information,
Roland Pibinger
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
White Wolf Guest
|
Posted: Sun Mar 13, 2005 12:33 pm Post subject: Re: std::bad_exception, sit, sit! |
|
|
Roland Pibinger wrote:
[SNIP]
| Quote: | That clause refers to exceptions that unexpected throws/rethrows.
If you read 15.5.1, (a few lines up from where you're looking) you'll
see the last of the conditions that terminate() is called is for when
you have a exception specificadtion violation and the DEFAULT
unexpected() is called.
The wording is fuzzy and contradictory in this case. Stroustrup wites
on his homepage ( http://www.research.att.com/~bs/3rd_issues.html )
that the "draft standard doesn't support the mapping of exceptions as
I describe it in 14.6.3" ("draft standard"!!) and "I have raised the
issue in the standards committee." No result of this effort is given.
This may be a defect in the standard that nobody cares to address.
|
Well, I honestly do not think there is an error in the standard. What it
says about the default behavior (when there is not user defined
unexpected-handler installed) is 100% clear. I would be happy, if the topic
could turn back to its original issue, and not to this one - which does not
exist.
Unfortunately people first read TCPL, which has an ambiguous statement about
the behavior you have been discussing. However, the standard is very clear
about this issue, and reading Stroustrup *after* you have read the standard
makes that statement clear as well.
I would like to discuss here the the original topic of the thread, and
kindly ask you, to open another thread for your topic, if it matters enough
to you.
The original topic was: what does it mean that "the exception-specification
does not include the class std::bad_exception"? This is a very clear topic
of its own.
The standards' text does not say, "if the exception specification covers",
or "if the exception specification allows". It says: includes. This is
clearly ambiguous. It can mean that the *text* we call exception
specification includes the *exact* type std::bad_exception *or* it may mean
that it *allows* that exception to be thrown. Both ways make sense. The
first, because we enable here a *change* of type, it is better be explicit,
and not a surprise. The latter, is to keep the meaning of exception
specifications simple - I honestly think that the latter is a weaker
argument.
Is there anyone here who can recall what was the intended meaning of that
text?
--
WW aka Attila
:::
"I am Homer of Borg. Prepare to be ...ooooh donuts!"
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
wade@stoner.com Guest
|
Posted: Tue Mar 15, 2005 8:30 pm Post subject: Re: std::bad_exception, sit, sit! |
|
|
White Wolf wrote:
| Quote: | The standards' text does not say, "if the exception specification
covers",
or "if the exception specification allows". It says: includes. This
is
clearly ambiguous. It can mean that the *text* we call exception
specification includes the *exact* type std::bad_exception *or* it
may mean
that it *allows* that exception to be thrown. Both ways make sense.
The
first, because we enable here a *change* of type, it is better be
explicit,
and not a surprise. The latter, is to keep the meaning of exception
specifications simple - I honestly think that the latter is a weaker
argument.
Is there anyone here who can recall what was the intended meaning of
that
text?
|
I certainly don't know the original intent. I'll note:
15.4/6 "An exception-specification ... can include classes that are
related by inheritance, ... doing so is redundant."
would imply to me that
void foo() throw(std::exception);
means the same thing as
void foo() throw(std::exception, std::bad_exception);
OTOH the standard does seem to make a distinction between the
exceptions that are "included" in the specification and the exceptions
that are "allowed." Specifically, 15.4/2 seems to say that the
following is illegal:
void foo() throw(std::exception);
void foo() throw(std::exception, std::bad_exception){}
[ 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
|
|