Topic: Exception gurus - Copy constructors of exceptions


Author: "Bradd W. Szonye" <bradds@concentric.net>
Date: 1998/02/06
Raw View
Nicholas howden wrote in message <6baodm$k23@netlab.cs.rpi.edu>...
>
>When is an exception's copy constructor called?

The simple version:

[T x;]
Start with the initial exception object, x.
[throw x;]
When you throw x, the mechanism copies it to a temporary "__t."
[catch (T & r) {...}]
If you catch by reference, the reference r is bound to __t.
[catch (T e) {...}]
If you catch by value, the value e is a copy of __t.

Note that "__t" is for exposition only; the temporary doesn't really
have a name.

There are some exceptions (pardon pun) to the rules above. Your compiler
may or may not implement them, and I don't know what the final rules in
the FDIS are. Roughly, if it does not change the behavior of the program
(other than the copy constructor and destructor calls), the compiler can
skip either copy.

Bradd W. Szonye
bradds@concentric.net
http://www.concentric.net/~Bradds


      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern/std-c++/faq.html                  ]





Author: "Tom McKearney" <no@spam.com>
Date: 1998/02/06
Raw View
Nicholas howden wrote in message <6baodm$k23@netlab.cs.rpi.edu>...
>Here is a tricky problem I currently have:
>
>When is an exception's copy constructor called?

As soon as you throw (I think).

>Stroustrup's C++ book says that "In principle, an exception is copied
>when
>it is thrown, so the handler gets hold of a copy of the original
>exception.". Does this apply when the exception is caught by reference?

There is a great discussion of this in either Effective C++ or More
Effective C++.
Here goes...

An exception's copy constructor is _always_ called upon a call to throw (one
with parameters).
If you are rethrowing without specifying variable name, it is not copied.

try
{
    myException ex;
    throw ex; // copied in memory
}
catch(myException& ex) // not copied
{
    throw; // also not copied
}

// ALSO: If you catch by value it copies twice!  And if you rethrow with a
variable name, it does it again!
try
{
    myException ex;
    throw ex; // copied in memory
}
catch(myException ex) // copied again!
{
    throw ex; // copied AGAIN!
}


>Is it always necessary to copy exceptions because the stack is being
>unwound and the originial objects are destroyed?

Exactly.

>Stroustrup also says that if an exception is caught by value as a Base
>class, then the handler does not have access to the attributes of the
>derived class. Is this simply because you cannot (legally) cast it
>upwards, or is the object actually copied as its base class in this
situation?

It is actually copied as the base class...

class baseException {};
class myException : baseException
{
public:
    int derivedVar;  // never do this - for demo purposes only
};

try
{
    myException ex;
    throw ex;
}
catch(baseException ex) // copied a baseException ONLY - no access to
derivedVar
{
    cout << ex.derivedVar; // ERROR
    cout << static_cast<myException>(ex).derivedVar; // ERROR - maybe
undefined - whatever!

    throw;
}

>When the call stack is unwound, is the exception copied at every level of
>indirection whether there is a handler or not at that level, or is it only
>copied where there is something to catch it? Is this implementation
>specific or a definition in ANSI C++?

I am guessing, but I believe that it is always copied, because you still get
an "unhandled exception" when you throw something that doesn't get caught.
This is only a guess though. Anyone else (with a lot more time on their
hands) who can quote the spec on this?

Hope this helps.

Tom McKearney



      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern/std-c++/faq.html                  ]





Author: bill@gibbons.org (Bill Gibbons)
Date: 1998/02/07
Raw View
In article <6bfa7t$f09@netlab.cs.rpi.edu>, tamlin@algonet.Sweden (Mike
Nordell) wrote:

> Bill Gibbons wrote:
>
> >In article <6baodm$k23@netlab.cs.rpi.edu>, Nicholas howden
> ><howden@lineone.net> wrote:
> >
> >> Here is a tricky problem I currently have:
> >>
> >> When is an exception's copy constructor called?
> >>
> >> Stroustrup's C++ book says that "In principle, an exception is copied
> >> when
> >> it is thrown, so the handler gets hold of a copy of the original
> >> exception.". Does this apply when the exception is caught by reference?
> >
> >Yes.  The copy occurs at the point of throw, independent of whether the
> >catch is by reference.  When the catch is by reference, the reference
> >is to the *copy* of the thrown object, not the original.
>
> Is this really required by the standard? My compiler generates one
> object at the point of the throw, then it "hands off" this instance to
> the catch-handler(s), and finally when they're done, it's destructed.
> This is my compilers default behaviour even when it's told to deliver
> non optimized debug code.

The object which it generates must be a temp with the *static* type of the
expression in the throw.  If the result of the expression is itself a temp,
the implementation may use that temp if it can arrange to extend its
lifetime; that is, it can elide the expression result temp so that the
expression result goes directly into the exception temp.

     struct B { };
     struct D : B { };
     D f();
     void g() {
         D d;
         throw d;   // copy to temp is required
         B &b = d;
         throw b;   // copy to temp (with slicing) is required
         throw f(); // nominally two temps and two copies, but
                    // one temp and copy could be elided
    }


-- Bill Gibbons
   bill@gibbons.org

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]



[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: David Abrahams <abrahams@motu.com>
Date: 1998/02/08
Raw View
Nicholas howden wrote:
>
> Here is a tricky problem I currently have:
>
> When is an exception's copy constructor called?
>
> Stroustrup's C++ book says that "In principle, an exception is copied when
> it is thrown, so the handler gets hold of a copy of the original
> exception.". Does this apply when the exception is caught by reference?

Yes. Stroustrup is only talking about what happens when the exception is
thrown. When they're caught by value they need to be copied again, in
principle.

> Is it always necessary to copy exceptions because the stack is being
> unwound and the originial objects are destroyed?

Not at every stack frame, if that's what you mean. The copy mentioned above
gets made upon throwing, into unspecified "magic memory" - it's not an auto
variable, so it doesn't get destroyed along with the auto variables in the
scope of the throw:

void foo()
{
  Exception x; // x gets destroyed when foo() exits
  throw x;     // makes a copy of x which lives until no longer being handled.
}

> Stroustrup also says that if an exception is caught by value as a Base
> class, then the handler does not have access to the attributes of the
> derived class. Is this simply because you cannot (legally) cast it
> upwards, or is the object actually copied as its base class in this
> situation?

In principle, the latter.

> When the call stack is unwound, is the exception copied at every level of
> indirection whether there is a handler or not at that level, or is it only
> copied where there is something to catch it? Is this implementation
> specific or a definition in ANSI C++?

According to the standard, the exception object may only be copied:

a. When initially thrown
b. When caught by value

The reason for saying "in principle" above is that any of these copies are
allowed to be optimized away in certain circumstances (see below). In short,
exception objects may be copied when thrown or caught by value... or not. You
are guaranteed that they won't be copied at any other time.

-Dave

----
Here are the specific sections of the standard which relate to the
copying of exceptions:

15.1:

3 A throw-expression initializes a temporary object, the type of which
is determined by removing any top-level cv-qualifiers from the static
type of the operand of throw and adjusting the type from "array of T"
or "function returning T" to "pointer to T" or "pointer to function
returning T", respectively. [Note: the tem-porary object created for a
throw-expression that is a string literal is never of type char* or
wchar_t*; that is, the special conversions for string literals from the
types "array of const char" and "array of const wchar_t" to the types
"pointer to char" and "pointer to wchar_t", respectively (4.2), are
never applied to a throw-expression. ] The temporary is used to
initialize the variable named in the matching handler (15.3). The type
of the throw-expression shall not be an incomplete type, or a pointer
or reference to an incomplete type, other than void*, const void*,
volatile void*, or const volatile void*. Except for these restrictions
and the restrictions on type matching mentioned in 15.3, the operand of
throw is treated exactly as a function argument in a call (5.2.2) or
the operand of a return statement.

4 The memory for the temporary copy of the exception being thrown is
allocated in an unspecified way, except as noted in 3.7.3.1. The
temporary persists as long as there is a handler being executed for
that exception. In particular, if a handler exits by executing a throw;
statement, that passes control to another handler for the same
exception, so the temporary remains. When the last handler being
executed for the exception exits by any means other than throw; the
temporary object is destroyed and the implementation may deallocate the
memory for the temporary object; any such deallocation is done in an
unspecified way. The destruction occurs immediately after the
destruction of the object declared in the exception-declaration in the
handler.

5 If the use of the temporary object can be eliminated without changing
the meaning of the program except for the execution of constructors and
destructors associated with the use of the temporary object (12.2),
then the exception in the handler can be initialized directly with the
argument of the throw expression. When the thrown object is a class
object, and the copy constructor used to initialize the temporary copy
is not accessible, the program is ill-formed (even when the temporary
object could otherwise be eliminated). Similarly, if the destructor for
that object is not accessible, the program is ill-formed (even when the
tempo-rary object could otherwise be eliminated).

6 A throw-expression with no operand rethrows the exception being
handled. The exception is reactivated with the existing temporary; no
new temporary exception object is created. The exception is no longer
considered to be caught; therefore, the value of uncaught_exception()
will again be true.

[Example: code that must be executed because of an exception yet cannot
completely handle the exception can be written like this:
try {
// ...
}
catch (...) { // catch all exceptions
// respond (partially) to exception
throw; // pass the exception to some
// other handler
}
-end example]

15.3:

17 When the exception-declaration specifies a class type, a copy
constructor is used to initialize either the object declared in the
exception-declaration or, if the exception-declaration does not specify
a name, a temporary object of that type. The object shall not have an
abstract class type. The object is destroyed when the handler exits,
after the destruction of any automatic objects initialized within the
handler. The copy constructor and destructor shall be accessible in the
context of the handler. If the copy constructor and destructor are
implicitly declared (12.8), such a use in the handler causes these
functions to be implicitly defined; otherwise, the program shall
provide a definition for these functions.

18 If the use of a temporary object can be eliminated without changing
the meaning of the program except for execution of constructors and
destructors associated with the use of the temporary object, then the
optional name can be bound directly to the temporary object specified
in a throw-expression causing the handler to be executed. The copy
constructor and destructor associated with the object shall be
accessible even when the temporary object is eliminated. *

19 When the handler declares a non-constant object, any changes to that
object will not affect the temporary object that was initialized by
execution of the throw-expression. When the handler declares a
reference to a non-constant object, any changes to the referenced
object are changes to the temporary object initialized when the
throw-expression was executed and will have effect should that object
be rethrown.

[except.terminate] 15.5.1 The terminate() function

1 In the following situations exception handling must be abandoned for
less subtle error handling techniques:  - when the exception handling
mechanism, after completing evaluation of the expression to be thrown
but before the exception is caught (15.1), calls a user function that
exits via an uncaught exception,134)

__________________ 134) For example, if the object being thrown is of a
class with a copy constructor, terminate() will be called if that copy
construc-tor exits with an exception during a throw.

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Jason Merrill <jason@cygnus.com>
Date: 1998/02/08
Raw View
>>>>> Mike Nordell <tamlin@algonet.Sweden> writes:

> Bill Gibbons wrote:

>> Yes.  The copy occurs at the point of throw, independent of whether the
>> catch is by reference.  When the catch is by reference, the reference
>> is to the *copy* of the thrown object, not the original.

> Is this really required by the standard? My compiler generates one
> object at the point of the throw, then it "hands off" this instance to
> the catch-handler(s), and finally when they're done, it's destructed.

That's because your compiler is allowed to elide the copy, and construct
the object directly.  You're still creating a new object.  If you say

  throw A(2395);

the compiler can construct the exception object directly.  If you say

  throw a;

the compiler has to make a copy of a.

>> Right.  Of course if you throw a pointer to a local object, you can
>> still end up with a dangling pointer.  The situation is similar to
>> returning a value from a function.

> Yikes! This sounds like M$'s MFC. They don't throw exceptions, they
> throw _pointers_ to exceptions, like:
>  throw new CException();

But that's not a local object.

Jason

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Ron Natalie <ron@sensor.com>
Date: 1998/02/05
Raw View
Nicholas howden wrote:
> When is an exception's copy constructor called?
>
> Stroustrup's C++ book says that "In principle, an exception is copied
> when it is thrown, so the handler gets hold of a copy of the original
> exception.".

This is actually codifed by the standard.

> Does this apply when the exception is caught by reference?

Yes.  The throw makes a copy, it must for the thrown object may
not exist outside the scope that the throw exists in.  The catch
if not by reference will make a second copy...

> Is it always necessary to copy exceptions because the stack is being
> unwound and the originial objects are destroyed?

That's the general idea.  The other choice would be to force objects
that would still be in scope in the block containing the try/catch.

> When the call stack is unwound, is the exception copied at every level
> of indirection whether there is a handler or not at that level, or is it
> only copied where there is something to catch it? Is this implementation
> specific or a definition in ANSI C++?

It is copied once in the context of the "throw" and then all the magic
happens and that object is either copied or reintroduced by reference
into the catch block.

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: bill@gibbons.org (Bill Gibbons)
Date: 1998/02/05
Raw View
In article <6baodm$k23@netlab.cs.rpi.edu>, Nicholas howden
<howden@lineone.net> wrote:

> Here is a tricky problem I currently have:
>
> When is an exception's copy constructor called?
>
> Stroustrup's C++ book says that "In principle, an exception is copied
> when
> it is thrown, so the handler gets hold of a copy of the original
> exception.". Does this apply when the exception is caught by reference?

Yes.  The copy occurs at the point of throw, independent of whether the
catch is by reference.  When the catch is by reference, the reference
is to the *copy* of the thrown object, not the original.

> Is
> it always necessary to copy exceptions because the stack is being
> unwound
> and the originial objects are destroyed?

Right.  Of course if you throw a pointer to a local object, you can
still end up with a dangling pointer.  The situation is similar to
returning a value from a function.

> Stroustrup also says that if an exception is caught by value as a Base
> class, then the handler does not have access to the attributes of the
> derived class. Is this simply because you cannot (legally) cast it
> upwards,
> or is the object actually copied as its base class in this situation?

There are two copies involved here.

  (1) At the throw...
      The object specified in the throw is copied into a temporary.
      If the expression has the form (*base_ptr), where the type of
      base_ptr is "base_class *", the type of the temporary is
      "base_class".  So the object is "sliced" at this point if the
      actual type (e.g. by typeid) of the object is derived from
      "base_class".

  (2) At the catch...
      The handler object is initialized in just the way that function
      parameters are initialized, using the temporary object as
      the "argument" and the handler object as the "parameter".
      This may or may not involve slicing, just as passing an argument
      to a function may or may not involve slicing.

> When the call stack is unwound, is the exception copied at every level
> of
> indirection whether there is a handler or not at that level, or is it
> only
> copied where there is something to catch it? Is this implementation
> specific or a definition in ANSI C++?

Only copied when a handler matches, as specified in the FDIS.
The copy occurs even if the declaration in the "catch" does not specify
a name; in this case, the exception is copied to an unnamed temp.


-- Bill Gibbons
   bill@gibbons.org

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: tamlin@algonet.Sweden (Mike Nordell)
Date: 1998/02/06
Raw View
Bill Gibbons wrote:

>In article <6baodm$k23@netlab.cs.rpi.edu>, Nicholas howden
><howden@lineone.net> wrote:
>
>> Here is a tricky problem I currently have:
>>
>> When is an exception's copy constructor called?
>>
>> Stroustrup's C++ book says that "In principle, an exception is copied
>> when
>> it is thrown, so the handler gets hold of a copy of the original
>> exception.". Does this apply when the exception is caught by reference?
>
>Yes.  The copy occurs at the point of throw, independent of whether the
>catch is by reference.  When the catch is by reference, the reference
>is to the *copy* of the thrown object, not the original.

Is this really required by the standard? My compiler generates one
object at the point of the throw, then it "hands off" this instance to
the catch-handler(s), and finally when they're done, it's destructed.
This is my compilers default behaviour even when it's told to deliver
non optimized debug code.

>> Is it always necessary to copy exceptions because the stack is being
>> unwound and the originial objects are destroyed?
>
>Right.  Of course if you throw a pointer to a local object, you can
>still end up with a dangling pointer.  The situation is similar to
>returning a value from a function.

Yikes! This sounds like M$'s MFC. They don't throw exceptions, they
throw _pointers_ to exceptions, like:
 throw new CException();
This is a PITA to handle:
 catch (std::exception& e) {}
 catch (CException* e) { e->Delete(); } // Really!

My compiler gives me that the catch-by-ref object is only constructed,
and after the catch, destructed.
The catch-by-value (usually a bad thing, slicing is one argument)
naturally copy-constructs.

>> Stroustrup also says that if an exception is caught by value as a Base
>> class, then the handler does not have access to the attributes of the
>> derived class. Is this simply because you cannot (legally) cast it
>> upwards, or is the object actually copied as its base class in this
>> situation?

(sorry for breaking in) This is usual C++ behaviour. A base-class
couldn't possibly have knowledge about it's subclasses. But the
following explanation is good:

>There are two copies involved here.
>
>  (1) At the throw...
>      The object specified in the throw is copied into a temporary.
>      If the expression has the form (*base_ptr), where the type of
>      base_ptr is "base_class *", the type of the temporary is
>      "base_class".  So the object is "sliced" at this point if the
>      actual type (e.g. by typeid) of the object is derived from
>      "base_class".
>
>  (2) At the catch...
>      The handler object is initialized in just the way that function
>      parameters are initialized, using the temporary object as
>      the "argument" and the handler object as the "parameter".
>      This may or may not involve slicing, just as passing an argument
>      to a function may or may not involve slicing.
>
>> When the call stack is unwound, is the exception copied at every level
>> of indirection whether there is a handler or not at that level, or is it
>> only copied where there is something to catch it? Is this implementation
>> specific or a definition in ANSI C++?
>
>Only copied when a handler matches, as specified in the FDIS.
>The copy occurs even if the declaration in the "catch" does not specify
>a name; in this case, the exception is copied to an unnamed temp.

As usual when I have to verify something, I make a small example code
to be compiled:

#include <iostream>

// It's a VC++4.2 thing. (STL and StdLib are in the global namespace)
// using std::cout;

class A
{
public:
    A() { cout << "A c'tor @0x" << this << endl; }
    A(const A& a)
    {
        cout << "A copy c'tor from " << &a << " to " << this << endl;
    }
    ~A() { cout << "A d'tor @0x" << this << endl; }
};

class Derived : public A
{
public:
    Derived() { cout << "Derived c'tor @0x" << this << endl; }
    Derived(const Derived& d)
    {
        cout << "Derived copy c'tor from " << &d << " to " << this <<
endl;
    }
    ~Derived() { cout << "Derived d'tor @0x" << this << endl; }
};

int main()
{
    try {
        throw A();
    }
    catch (A& a) {
        cout << "  catched A&, addr of A object is " << &a << endl;
    }
    cout << "'between the catches 1" << endl;
    try {
        throw A();
    }
    catch (A a) {
        cout << "  catched A, and this one is at " << &a << endl;
    }
    cout << "'between the catches 2" << endl;
    try {
        throw Derived();
    }
    catch (A& a) {
        cout << "  catched A&, addr of A object is " << &a << endl;
    }
    cout << "'between the catches 3" << endl;
// Now slices
    try {
        throw Derived();
    }
    catch (A a) {
        cout << "  catched A, and this one is at " << &a << endl;
    }

    return 0;
}

---------------- end -------------------

Check out for your self how your compiler's handling it.
It would be nice to know how different compilers treat this.

&Mike

Change 'Sweden' to 'se' to reply by mail.

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Justin Vallon <vallon@pearl.fi.bear.com>
Date: 1998/02/06
Raw View
Nicholas howden <howden@lineone.net> writes:

> Here is a tricky problem I currently have:
>
> When is an exception's copy constructor called?
>
> Stroustrup's C++ book says that "In principle, an exception is copied
> when
> it is thrown, so the handler gets hold of a copy of the original
> exception.". Does this apply when the exception is caught by reference?
> Is
> it always necessary to copy exceptions because the stack is being
> unwound
> and the originial objects are destroyed?

Yes.  In order for the object to exist after the stack frame is unwound
(and the object being thrown is destructed), it must be copied [on
machines that store automatic variables in stack frames?].

> Stroustrup also says that if an exception is caught by value as a Base
> class, then the handler does not have access to the attributes of the
> derived class. Is this simply because you cannot (legally) cast it
> upwards,
> or is the object actually copied as its base class in this situation?

I would guess that it is copied, since you catch by value.  It should
be just like the polymorphism issue:

class A {};
class B : public A {};

void f(A a) {
}

void g() {
 B b;
 f(b); // Slices b.
}

try {
 B b;
 throw b; // slices b
} catch (A a) {
 throw;   // This will rethrow b.
 throw a; // This throws the sliced object.
}

Of course, if you don't care about slicing, you can catch A.

> When the call stack is unwound, is the exception copied at every level
> of
> indirection whether there is a handler or not at that level, or is it
> only
> copied where there is something to catch it? Is this implementation
> specific or a definition in ANSI C++?

I don't know about whether it is ANSI C++, but I don't think it is going
to be doing any redundant copy-construction.

--
-Justin
vallon@bear.com

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]



[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Nicholas howden <howden@lineone.net>
Date: 1998/02/04
Raw View
Here is a tricky problem I currently have:

When is an exception's copy constructor called?

Stroustrup's C++ book says that "In principle, an exception is copied
when
it is thrown, so the handler gets hold of a copy of the original
exception.". Does this apply when the exception is caught by reference?
Is
it always necessary to copy exceptions because the stack is being
unwound
and the originial objects are destroyed?

Stroustrup also says that if an exception is caught by value as a Base
class, then the handler does not have access to the attributes of the
derived class. Is this simply because you cannot (legally) cast it
upwards,
or is the object actually copied as its base class in this situation?

When the call stack is unwound, is the exception copied at every level
of
indirection whether there is a handler or not at that level, or is it
only
copied where there is something to catch it? Is this implementation
specific or a definition in ANSI C++?

Thanks in advance for the help,
Nick Howden.


      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]