Topic: Defect Report: Catching exceptions in constructor initializers


Author: Darin Adler <darin@bentspoon.com>
Date: 2000/03/09
Raw View
In article <38C588A1.355C25FF@corvu.com.au>, Bruce Mellows
<bruce@corvu.com.au> wrote:

> In the C++ standard (ISO/IEC 14882 First Edition 1998-09-01).
>
> In the handling of exceptions during constructor initialization, if
> the user does not throw at the end of the catch body, the object will
> be considered to be in a "good" state, and will be destructed
> normally.

Did you miss the following language in 15.3/16?

   "The exception being handled is rethrown if control reaches the end
    of a handler of the function-try-block of a constructor or
    destructor."

Given this, I think your defect report is incorrect.

    -- Darin

---
[ 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: Bruce Mellows <bruce@corvu.com.au>
Date: 2000/03/08
Raw View
In the C++ standard (ISO/IEC 14882 First Edition 1998-09-01).

In the handling of exceptions during constructor initialization, if the user
does not throw at the end of the catch body, the object will be considered to
be in a "good" state, and will be destructed normally.

This is demonstrated in the code supplied (I compile it with gcc 2.95.2).

I have also provided what I think are the modifications the the grammar that
enforce correct usage of this feature, i.e. the user is forced to throw at the
end of this type of catch.

/* begin demo.cpp */
#include <iostream>

static bool rethrow_exception;

struct foo
{
 foo()
 {
  cout << "foo::foo " << (void*)this << endl;
 }
 ~foo()
 {
  cout << "foo::~foo " << (void*)this << endl;
 }
};

struct bar
{
 bar()
 {
  cout << "bar::bar (throws) " << (void*)this << endl;
  throw int(0);
 }
 ~bar()
 {
  cout << "bar::~bar " << (void*)this << endl;
 }
};

struct foobar
{
 foo m_foo;
 bar m_bar;

 foobar();
 ~foobar()
 {
  cout << "foobar::~foobar " << (void*)this << endl;
 }
};

foobar::foobar()
try
// bar throws in its constructor
{
 cout << "foobar::foobar " << (void*)this << endl;
}
catch(...)
{
 cout << "caught exception in constructor initializers" << endl;
 if (rethrow_exception)
  throw;
}

void
demo(bool rethrow)
{
 try
 {
  rethrow_exception = rethrow;
  cout << "\nconstructing foobar with rethrow_exception=" <<
(rethrow?"true":"false") << endl;
  foobar fb;
 }
 catch(...)
 {
  cout << "unknown exception caught" << endl;
 }
}

int main()
{
 demo(true);
 demo(false);

 return 0;
}
/* end demo.cpp */

/* begin grammar changes in A.5 Statements */
+compound-statement-throw:
+ '{' [statement-seq] throw-expression '}'


in A.13 Exception handling

-function-try-block:
- 'try' [ctor-initializer] function-body handler-seq
+function-try-block:
+ 'try' [ctor-initializer] function-body function-handler-seq

+function-handler-seq:
+ function-handler [function-handler-seq]

+function-handler:
+ 'catch' '(' exception-declaration ')' compound-statement-throw
/* end grammar changes */


Bruce Mellows



[ 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              ]