Topic: exceptions in ctor init


Author: bmellows@my-deja.com
Date: 2000/01/14
Raw View
I believe I have found a small deficiency 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.


*** changes to the grammar...

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


*** An example that demonstrates this problem...

#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;
}


Sent via Deja.com http://www.deja.com/
Before you buy.


[ 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: "Dave Abrahams" <abrahams@mediaone.net>
Date: 2000/01/15
Raw View
In article <85ltoc$tvg$1@nnrp1.deja.com> , bmellows@my-deja.com  wrote:

> I believe I have found a small deficiency 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).

What you have found is a bug in your compiler. From section 15.3 in the
standard:

15If  a  return statement appears in a handler of the function-try-block
  of a constructor, the program is ill-formed.

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

So your code should behave the same whether rethrow_exception is true or
false.

-Dave

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