Topic: Constructor initializer exception catching can be disasterous


Author: Bruce Mellows <bruce@corvu.com.au>
Date: 2000/03/16
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 (expect sparks to come
out of the keyboard - so stand back).

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

I believe that the grammar needs to be modified to ensure that a throw occurs
at the end of the catch for a constructor initializer.


Actually I believe this is a defect in C++, but I don't know who to tell, or
even how to say it.


/* 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 */

---
[ 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: Darin Adler <darin@bentspoon.com>
Date: 2000/03/17
Raw View
In article <38D016BF.5BA5BD2A@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 (expect sparks to come out of the keyboard - so stand back).
>
> This is demonstrated in the code supplied (I compile it with gcc 2.95.2).
>
> I believe that the grammar needs to be modified to ensure that a
> throw occurs at the end of the catch for a constructor initializer.
>
>
> Actually I believe this is a defect in C++, but I don't know who to
> tell, or even how to say it.

The standard does ensure that a throw occurs. Did you miss the following
text 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."

I don't think a defect report is necessary.

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