Rethrowing "finished" exception?

C

Chris Newcombe

Please could someone on the VC++ 7.0 compiler team (note; not 7.1)
tell me if this code is handled 'correctly' (i.e. as the original
poster suggests) in all cases?

http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&[email protected]

(Incase the URL doesn't make it I've copied it below.)

I have a situation where I really need this technique. But the fact
that Dave Abrahams wasn't sure about it very much worries me...

Many thanks,

Chris Newcombe, Valve Software.

------------

From: "Bill Wade" <[email protected]>
Subject: Defect Report: Rethrowing "finished" exception?
Date: 2000/02/29
Message-ID: <[email protected]>#1/1
Newsgroups: comp.std.c++

Paragraph seven of "15.1 Throwing an exception" [except.throw]
discusses which exception is thrown by a throw-expression with no
operand.

May an expression which has been "finished (15.1p7)" by an inner catch
block be rethrown by an outer catch block?

catch(...) // Catch the original exception
{
try{ throw; } // rethrow it at an inner level (in reality this is
probably inside a function)
catch (...)
{
} // Here, an exception (the original object) is "finished"
according to 15.1p7 wording

// 15.1p7 says that only an unfinished exception may be rethrown.
throw; // Can we throw it again anyway? It is certainly still
alive (15.1p4).
}

I believe this is ok, since the paragraph says that the exception is
finished when the "corresponding" catch clause exits. However since
we have two clauses, and only one exception, it would seem that the
one exception gets "finished" twice.
 
C

Chris Newcombe

Carl Daniel said:
I agree with James Kuyper & Dave Abrahams that the code presented in the
original posting probably should call terminate(), according to the
standard.

Thanks Carl. However I think Dave Abrahams was actually agreeing with
the original poster, that the code should be OK...
Dave Abrahams wrote:
(e-mail address removed) wrote on 2/29/00 6:04 AM:

FWIW, I agree that your interpretation is the only one that makes sense.


FWIW, both VC7 and VC7.1 (but not VC6) appear to implement what you want
this code to mean:

Thanks -- yes I'm already using it and it appears to work. However
given the apparent ambuiguity of the standard I'd really like to get
an authoratative statement from the compiler developers that the code
generated is correct in all cases (i.e. has no side effects, and isn't
just acceidentally appearing to work).

I do plan to ask on comp.std.c++ but any defect report or ambiguity
resolution will be far too late to affect my current project. I
really need to know asap if this technique is practically safe with
the current VC++ 7.0 compiler.

Is there a developer on this list who worked on exception handling?

regards,

Chris
 
C

Carl Daniel [VC++ MVP]

Chris said:
Thanks -- yes I'm already using it and it appears to work. However
given the apparent ambuiguity of the standard I'd really like to get
an authoratative statement from the compiler developers that the code
generated is correct in all cases (i.e. has no side effects, and isn't
just acceidentally appearing to work).

I do plan to ask on comp.std.c++ but any defect report or ambiguity
resolution will be far too late to affect my current project. I
really need to know asap if this technique is practically safe with
the current VC++ 7.0 compiler.

Is there a developer on this list who worked on exception handling?

I've raised the issue to the VC team, requesting that someone from the
compiler team comment on your question. From what I understand about how VC
implements exception handling, you're safe in relying on the current
behavior for at least VC7 and 7.1 - of course, there's no guarantee about
the future.

I don't have access to any other compilers, but my guess is that the
behavior of the VC-compiled application is a side-effect of how VC layers
C++ EH on top of Win32 structured exception handling. I would expect other
implementations to probably not have the behavior you're counting on. Under
the VC model, the "catch clause" is effectively called as if it was a
subroutine called at the point of the throw. Under most other models, the
catch clause is entered as-if by longjump after the stack has been unwound.
In that model, it seems likely to me that the exception object will be
destroyed by the middle catch clause and the attempted re-throw will result
in a call to terminate().

-cd
 
V

Visual C++ Team

From: (e-mail address removed) (Chris Newcombe)
Thanks -- yes I'm already using it and it appears to work. However
given the apparent ambuiguity of the standard I'd really like to get
an authoratative statement from the compiler developers that the code
generated is correct in all cases (i.e. has no side effects, and isn't
just acceidentally appearing to work).

I do plan to ask on comp.std.c++ but any defect report or ambiguity
resolution will be far too late to affect my current project. I
really need to know asap if this technique is practically safe with
the current VC++ 7.0 compiler.

Is there a developer on this list who worked on exception handling?

I implemented the fix in the CRT to get this example working in VC++ 7.0,
back about 4 years ago. Under the current implementation, when a catch
block exits via normal fall-through, the exception object will be destroyed
except when the catch block is nested within some other catch block which
is using the same exception object.

Now as it turns out, Bill Wade submitted this as a defect report back in
Feb 2000 (see issue 208,
http://www.comeaucomputing.com/iso/cwg_defects.html#208). That DR has a
status of WP, which means that the standards committee has voted to apply
the issue to the current Working Paper. That is, this will be officially
fixed in the C++0x, but not in the current standard. I have no information
on just why that is.

As it stands, yes, you can count on VC++ 7.0 and beyond to act as you wish
here, since we went out of our way to make sure that was true. The earlier
implementation would just destroy the exception object when exiting a catch
block via fall-through, even when nested within another catch block.

Do note that this behavior is not guaranteed by the current C++ standard,
so it's not likely to be portable, as Carl Daniel stated.

...Phil (one-time VC++ CRT dev)
 
C

Carl Daniel [VC++ MVP]

Visual C++ Team said:
As it stands, yes, you can count on VC++ 7.0 and beyond to act as you
wish here, since we went out of our way to make sure that was true.
The earlier implementation would just destroy the exception object
when exiting a catch block via fall-through, even when nested within
another catch block.

Do note that this behavior is not guaranteed by the current C++
standard, so it's not likely to be portable, as Carl Daniel stated.

Thanks for the gorey details, Phil!

-cd
 
C

Chris Newcombe

I implemented the fix in the CRT to get this example working in VC++ 7.0,
back about 4 years ago.

Great stuff -- thankyou very much for taking the time to give this much detail.

regards,

Chris (much relieved :)
 

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

Top