(ref.doc)vinoski 230693

Next verdonck 250693 Prev: vinoski 150693 Up: Usenet

Newsgroups: comp.std.c++,comp.lang.c++
From: [email protected] (Steve Vinoski) (Note:
 Vinoski)
Subject: Re: lifetime of temporary copy of exception
Date: Wed, 23 Jun 1993 02:26:59 GMT
Distribution: comp
Nntp-Posting-Host: srv.ch.apollo.hp.com
Organization: Hewlett-Packard Corporation, Chelmsford, MA

In article <[email protected]> [email protected] (Ronald F. Guilmette) writes:
>In article <[email protected]> [email protected] writes:
>>Hi netters!
>>
>>I am about to recommend to people in my team the following way of
>>using exceptions:
>>
>>class Exception { /*...*/ };
>>
>>void foo() {
>>  // ...
>>  throw Exception(/*...*/);
>>  // ...
>>}
>>
>>void bar() {
>>  try {
>>    // ...
>>    foo();
>>    // ...
>>  }
>>  catch (Exception& e) { /*...*/ }
>>}
>>
>>I am a bit worried by the lifetime of the temporary copy of the
>
>As well you should be.  This looks like a similar issue to:
>
>	int a, b;
>	const int& returner () { return a+b; }
>
>I believe that the memory used to hold the sum in this case may be recycled
>for other uses after the function exits.  That would leave you with a
>dangling reference.

I don't think your example is the same as his.  The 01/28/93 ANSI C++
draft shows an example in section 15.2 on page 15-2 that is exactly
like Marc Girod's example (see also page 357 of the ARM).

The text below it says:

"A throw-expression initializes a temporary object of the static type
of the operand of throw and uses that temporary to initialize the
appropriately-typed variable named in the handler."

Later on page 15-5 in section 15.7 the working paper states:

"The formal argument of a catch clause obeys the same access rules as
an argument of the function in which the catch clause occurs."

I take these two statements to mean that no dangling reference will
occur if I throw a temporary and catch it by reference.  For what it's
worth, the HP C++ implementation of exceptions works in this manner.

>In the case of your example however, I don't think that your catch clase
>would be invoked after the throw.  If however you had said:
>
>	catch (const Exception& e) { /*...*/ }
>
>...then maybe it would be.
>
>I think this is the way thing have to work, because your constructor does
>not (I believe) yield an lvalue.  Thus, the value it yields cannot be used
>to initialize a reference to a non-const thing of any type.

In section 15.4 on page 15-3 (page 359 of the ARM) it says:

"A handler with type T, const T, T&, or const T& is a match for a
throw expression with an object of type E if

  [1] T and E are the same type, or
  [2] T is an accessible base class of E at the throw point, or
  [3] T is a pointer type and E is a pointer type that can be
      converted to T by a standard pointer conversion at the throw
      point."

Thus, I don't think the presence of const in the catch clause matters
in Marc's example.

>>Exception thrown, used for the initialisation of the parameter of the
>>catch block.
>>
>>The best I found to tranquilise me, was the comment of an example in
>>the ARM:
>>
>>Section 15.2c, p 357
>>  "Here the reference _oo_ will refer to a copy of _dummy_. It cannot
>>  refer to the automatic storage of function _g()_ from which control
>>  is returned by _throw_. The copy of the expression created by
>>  _throw_, however, will persist until exit from the exception
>>  handler."
>
>I think you may be misreading that, but I would agree that the rules are
>rather murkey here.

I agree that the rules are murky and are not finalized, but I think
he's reading things correctly.  I know that the HP C++ exceptions
implementation goes to great lengths to ensure that such temporaries
are properly available to the catch clause.  See the paper from the HP
California Language Labs folks in the 1992 Usenix C++ Conference
proceedings for some good clarification of these issues.

--steve

Steve Vinoski  (508)436-5904   [email protected]
Distributed Object Computing Program
Hewlett-Packard, Chelmsford, MA 01824       These are my opinions.


automatically generated by info2www version 1.2.2.8