Boost logo

Boost :

From: Scott McMurray (me22.ca+boost_at_[hidden])
Date: 2008-05-06 23:11:06


On Tue, May 6, 2008 at 10:47 PM, shiwei xu <xushiweizh_at_[hidden]> wrote:
> Your question is very interesting. I thought it before. In fact I don't know
> a perfect solution. If the constructor of an object throws, should the
> destructor be called?
>
> class Foo
> {
> private:
> A m_a;
> B m_b;
> C m_c;
>
> public:
> Foo() {
> m_a.init();
> m_b.init();
> thow std::exception("error");
> m_c.init();
> }
> ~Foo() {
> ...
> }
> };
>
> Suppose we initialized m_a and m_b. m_c was uninitialized when the exception
> throws. If the destructor is called, it may cause a crash. If the destructor
> isn't called, the allocated memory of m_a and m_b will be leaked.
>
> I choose to call the destructor because I think that a crash is easy to be
> detected and be solved.
>

This is a non-point. Go read the rules for which destructors are
called when exceptions are thrown in different places. If A and B are
written properly, there's no problem. And in any case, throwing in a
constructor for an automatic variable doesn't call the destructor, so
no matter what you think, you shouldn't call the destructor, since
it'll break expectations.

Here's a simple counter-example:
int *bar() {
    throw 0;
    return new int(42);
}
struct foo {
    int *p;
    foo() : p(bar()) {}
    ~foo() { delete p; }
};

Quite obviously UB to call that destructor.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk