 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Niklas Matthies Guest
|
Posted: Thu Dec 15, 2005 10:44 am Post subject: Rethrowing from destructors |
|
|
What is the behavior of the following program?
struct X
{
~X() { throw; }
};
int main()
{
try
{
X x;
throw 0;
}
catch (...) { }
}
Does the throw statement in the destructor a) rethrow the outer
exception, or does it b) call std::terminate(), or does it c) rethrow
the outer exception which then causes std::terminate() to be called
upon leaving the destructor?
-- Niklas Matthies
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Maciej Sobczak Guest
|
Posted: Thu Dec 15, 2005 2:21 pm Post subject: Re: Rethrowing from destructors |
|
|
Niklas Matthies wrote:
| Quote: | What is the behavior of the following program?
struct X
{
~X() { throw; }
};
int main()
{
try
{
X x;
throw 0;
}
catch (...) { }
}
|
The behavior is that the terminate() function will be called (15.1/ .
This is because at the time the ~X destructor is called, no exception is
being *handled*. Re-throwing of an exception is basically allowed only
*after* the catch clause is entered, which is not the case here.
--
Maciej Sobczak : http://www.msobczak.com/
Programming : http://www.msobczak.com/prog/
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Earl Purple Guest
|
Posted: Thu Dec 15, 2005 2:22 pm Post subject: Re: Rethrowing from destructors |
|
|
Niklas Matthies wrote:
| Quote: | What is the behavior of the following program?
struct X
{
~X() { throw; }
};
int main()
{
try
{
X x;
throw 0;
}
catch (...) { }
}
Does the throw statement in the destructor a) rethrow the outer
exception, or does it b) call std::terminate(), or does it c) rethrow
the outer exception which then causes std::terminate() to be called
upon leaving the destructor?
-- Niklas Matthies
|
Refer to this:
http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.3
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
kanze Guest
|
Posted: Thu Dec 15, 2005 2:23 pm Post subject: Re: Rethrowing from destructors |
|
|
Niklas Matthies wrote:
| Quote: | What is the behavior of the following program?
struct X
{
~X() { throw; }
};
int main()
{
try
{
X x;
throw 0;
}
catch (...) { }
}
Does the throw statement in the destructor a) rethrow the
outer exception, or does it b) call std::terminate(), or does
it c) rethrow the outer exception which then causes
std::terminate() to be called upon leaving the destructor?
|
Interesting question. On reading the standard, I'd say that
std::terminate() will be called, immediately. The standard says
(§15.1/ : "If no expcetion is presently being handled,
executing a throw-expression with no operand calls terminate()."
I don't see an exact definition of "handled" off hand, but given
the use of "handler", and "handling an exception" in the title
of §15.3, I'd suppose that "being handled" means "executing code
in a catch block".
Both g++ (4.0.2) and Sun CC (5.5) agree with this
interpretation.
I do hope that the question is one of idle curiosity, and that
you aren't trying to use something like this in actual code:-).
--
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 |
|
 |
Stefan Näwe Guest
|
Posted: Thu Dec 15, 2005 2:24 pm Post subject: Re: Rethrowing from destructors |
|
|
Niklas Matthies wrote:
| Quote: | What is the behavior of the following program?
struct X
{
~X() { throw; }
};
|
You're not catching anything here, so (from the holy standard):
15.1 Throwing an exception (p. 293)
8 If no exception is presently being handled, executing a throw expression
with no operand calls terminate() (15.5.1).
| Quote: |
int main()
{
try
{
X x;
throw 0;
}
catch (...) { }
}
Does the throw statement in the destructor a) rethrow the outer
exception, or does it b) call std::terminate(), or does it c) rethrow
the outer exception which then causes std::terminate() to be called
upon leaving the destructor?
|
/S
--
Stefan Naewe
naewe.s_AT_atlas_DOT_de
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Niklas Matthies Guest
|
Posted: Thu Dec 15, 2005 11:20 pm Post subject: Re: Rethrowing from destructors |
|
|
On 2005-12-15 14:23, kanze wrote:
| Quote: | Niklas Matthies wrote:
What is the behavior of the following program?
:
Does the throw statement in the destructor a) rethrow the
outer exception, or does it b) call std::terminate(), or does
it c) rethrow the outer exception which then causes
std::terminate() to be called upon leaving the destructor?
Interesting question. On reading the standard, I'd say that
std::terminate() will be called, immediately. The standard says
(§15.1/ : "If no expcetion is presently being handled,
executing a throw-expression with no operand calls terminate()."
I don't see an exact definition of "handled" off hand, but given
the use of "handler", and "handling an exception" in the title
of §15.3, I'd suppose that "being handled" means "executing code
in a catch block".
|
Yeah, what my question comes down to is that I wasn't sure about the
exact meaning of "handled", and older (well, ancient) versions of g++
acted like c).
:
| Quote: | I do hope that the question is one of idle curiosity, and that
you aren't trying to use something like this in actual code:-).
|
The former; the question crossed my mind when I was thinking about the
behavioral differences between destructors and Andrei's on_scope_xxx
blocks as defined by his code transformations.
-- Niklas Matthies
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
kanze Guest
|
Posted: Fri Dec 16, 2005 11:55 am Post subject: Re: Rethrowing from destructors |
|
|
Niklas Matthies wrote:
| Quote: | On 2005-12-15 14:23, kanze wrote:
Niklas Matthies wrote:
What is the behavior of the following program?
Does the throw statement in the destructor a) rethrow the
outer exception, or does it b) call std::terminate(), or
does it c) rethrow the outer exception which then causes
std::terminate() to be called upon leaving the destructor?
Interesting question. On reading the standard, I'd say that
std::terminate() will be called, immediately. The standard
says (§15.1/ : "If no expcetion is presently being handled,
executing a throw-expression with no operand calls
terminate()." I don't see an exact definition of "handled"
off hand, but given the use of "handler", and "handling an
exception" in the title of §15.3, I'd suppose that "being
handled" means "executing code in a catch block".
Yeah, what my question comes down to is that I wasn't sure
about the exact meaning of "handled", and older (well,
ancient) versions of g++ acted like c).
|
The problem is that the standard doesn't actually define
"handled", as far as I can see. I'm just guessing that
"being handled" means "executing code in a handler", and it is
fairly clear that a "handler" corresponds exactly to what we
would generally call a catch block.
There are other hints: §15.1/6 mentions that "the value of
uncaught_exception() will AGAIN be true," which sort of suggests
that the statement is only legal when uncaught_exception() would
have been false. And ¹5.1/7 says that "The exception thrown is
the one most recently caught and not finished," which seems
pretty clear, even if it is not expressed as a constraint on
user code.
There is an interesting problem, however: take your code, and
set it in a catch block of another exception. What does happen
when you execute "throw ;" during stack walkback of an exception
which occurs when you are handling another exception? The
exception "most recently caught and not finished" is the outer
exception, so presumably, the "throw" is legal. My guess is
that in this case, c) would be the correct behavior, but it's
really only a guess.
--
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 |
|
 |
Bob Hairgrove Guest
|
Posted: Fri Dec 16, 2005 1:41 pm Post subject: Re: Rethrowing from destructors |
|
|
On 15 Dec 2005 05:44:02 -0500, Niklas Matthies
<usenet-nospam (AT) nmhq (DOT) net> wrote:
| Quote: | What is the behavior of the following program?
struct X
{
~X() { throw; }
};
int main()
{
try
{
X x;
throw 0;
}
catch (...) { }
}
Does the throw statement in the destructor a) rethrow the outer
exception, or does it b) call std::terminate(), or does it c) rethrow
the outer exception which then causes std::terminate() to be called
upon leaving the destructor?
|
Rethrowing an exception should only be legal within the catch block
itself. Clearly, it isn't, so terminate should be called (IMHO -- it
is not clear to me exactly in what scope we are when X is destroyed).
When the first throw statement is executed, the destructor of X will
be called before the code in the catch block is reached because X goes
out of scope immediately. The catch block will only catch exceptions
which were thrown within the context of the previous try block. The
question is, are we still "inside the try block" when X is destroyed?
I wouldn't count on it.
Two possibilities exist: either we are still inside the scope of the
try block, or we are somewhere "in between" the try and catch scopes.
If we are inside the try block, then the second exception is thrown
while the first is as yet unhandled, thus causing terminate to be
called. If we are "in between", then there is no catch block
corresponding to that scope, also causing terminate to be called.
--
Bob Hairgrove
[email]NoSpamPlease (AT) Home (DOT) com[/email]
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Niklas Matthies Guest
|
Posted: Fri Dec 16, 2005 1:42 pm Post subject: Re: Rethrowing from destructors |
|
|
On 2005-12-16 11:55, kanze wrote:
:
| Quote: | There is an interesting problem, however: take your code, and set it
in a catch block of another exception. What does happen when you
execute "throw ;" during stack walkback of an exception which occurs
when you are handling another exception? The exception "most
recently caught and not finished" is the outer exception, so
presumably, the "throw" is legal.
My guess is that in this case, c) would be the correct behavior, but
it's really only a guess.
|
Indeed interesting. Then what about:
struct X
{
~X()
{
try { throw; } catch (...) { }
}
};
int main()
{
try
{
throw 1;
}
catch (...)
{
{ X x; }
// (*)
}
}
Is the exception still being "handled" at (*)?
Also note that if such re-throws are indeed legal, it provides a way
to inspect _all_ exceptions currently being handled (not just the
latest one) from within the innermost handler by using nested
destructors.
My guess is that this is actually a defect in the standard and that
the intent was that re-throws are illegal whenever the topmost
exception on the exception stack is not currently being "handled".
-- Niklas Matthies
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Niklas Matthies Guest
|
Posted: Fri Dec 16, 2005 1:44 pm Post subject: Re: Rethrowing from destructors |
|
|
On 2005-12-16 11:55, kanze wrote:
:
| Quote: | The problem is that the standard doesn't actually define
"handled", as far as I can see. I'm just guessing that
"being handled" means "executing code in a handler", and it is
fairly clear that a "handler" corresponds exactly to what we
would generally call a catch block.
|
Actually 15.3p8 comes close to a definition: "An exception is
considered handled upon entry to a handler".
| Quote: | There is an interesting problem, however: take your code, and
set it in a catch block of another exception. What does happen
when you execute "throw ;" during stack walkback of an exception
which occurs when you are handling another exception? The
exception "most recently caught and not finished" is the outer
exception, so presumably, the "throw" is legal. My guess is
that in this case, c) would be the correct behavior, but it's
really only a guess.
|
Ignore the first reply I just made to this (hasn't been moderated yet
as I'm writing this); destructors are immaterial to what I described.
The only interesting thing about destructors here is that apparently
they can pull handled exceptions from under unhandled ones, so that
the exception stack actually isn't a proper stack any more.
My conclusion that this is probably a defect still stands, though.
-- Niklas Matthies
[ 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
|
|