0% found this document useful (0 votes)
43 views2 pages

C++: How Does RAII Work When A Constructor Throws An Exception?

The document discusses how RAII (Resource Acquisition Is Initialization) works when a constructor throws an exception in C++. While a constructor throwing will prevent its object's destructor from running, any member objects that completed construction will have their destructors called during stack unwinding. Smart pointers ensure resources are cleaned up properly in this case, unlike raw pointers. So in summary, RAII guarantees cleanup of acquired resources even if the constructor fails through calling member destructors.

Uploaded by

broeckho
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
43 views2 pages

C++: How Does RAII Work When A Constructor Throws An Exception?

The document discusses how RAII (Resource Acquisition Is Initialization) works when a constructor throws an exception in C++. While a constructor throwing will prevent its object's destructor from running, any member objects that completed construction will have their destructors called during stack unwinding. Smart pointers ensure resources are cleaned up properly in this case, unlike raw pointers. So in summary, RAII guarantees cleanup of acquired resources even if the constructor fails through calling member destructors.

Uploaded by

broeckho
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 2

C++: How does RAII work when a constructor throws an except... file:///Users/broeckho/usr/tmp/c-how-does-raii-work-when-a-con...

C++: How does RAII work when a constructor throws an exception?

I am learning about the RAII idiom in C++, and how to use smart pointers.

In my reading, I have come across two things that, to me, seem to contradict each other.

Quoted from http://www.hackcraft.net/raii/:

...if a member object with RAII semantics has been created and an exception happens before the
constructor has completed then its destructor will be called as part of the stack unwinding. Hence an
object which controls multiple resources can guarnatee their cleanup even if it isn’t fully constructed by
using member RAII objects.

But quoted from http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.10:

If a constructor throws an exception, the object's destructor is not run. If your object has already done
something that needs to be undone (such as allocating some memory, opening a file, or locking a
semaphore), this "stuff that needs to be undone" must be remembered by a data member inside the
object.

And then the second linked source recommends using smart pointers to deal with the issue of things that
were already allocated in the constructor.

So what actually happens in these scenarios?

c++ exception constructor raii

asked Feb 3 at 0:57


newprogrammer
594 1 9
100% accept rate

5 +1 this is the way that "newprogrammer[s]" should ask questions! – Cody Gray Feb 3 at 4:15

feedback

3 Answers

You're misunderstanding the first quote. That's not hard, since it's confusing.

if a member object with RAII semantics has been created and an exception happens before the
constructor has completed then its destructor will be called as part of the stack unwinding.

That's what it says. Here's what it meant:

if a member object with RAII semantics has been created and an exception happens in the outer object
before the outer object's constructor has completed then the member object's destructor will be called
as part of the stack unwinding.

See the difference? The idea is that the member object completed its constructor, but the owning type didn't.
It threw somewhere in its constructor. This will cause the destructor of all of its members to be called, but not
its own destructor.

Here's an example:

class  SomeType
{
   InnerType  val;
public:
   SomeType()  val(...)
   {
       throw  Exception;

1 of 2 21/12/12 10:21
C++: How does RAII work when a constructor throws an except... file:///Users/broeckho/usr/tmp/c-how-does-raii-work-when-a-con...

   }
};

When you create a SomeType instance, it will call InnerType::InnerType . As long as that doesn't throw,
it will then enter SomeType 's constructor. When that throws, it will cause val to be destroyed, thus calling
InnerType::~InnerType .

answered Feb 3 at 1:00


Nicol Bolas
78k 7 73 140

Ah that makes sense... By the way, are you the one who wrote the wonderful 3d graphics guide? I can't thank
you enough how great that guide is. – newprogrammer Feb 3 at 1:08

1 "This will cause the destructor of all of its members to be called, but not its own destructor." - well, just the ones
that had completed construction before the exception was thrown.... – Tony D Feb 3 at 1:30

feedback

There's no contradiction here; there's just some confusing terminology being used in different contexts.

If an object's constructor throws an exception, then the following occurs (assuming the exception is caught):

1. All local variables in the constructor have their destructors invoked, releasing all resources they've
acquired (if any).
2. All of the direct subobjects of the object whose constructor threw an exception will have their
destructors invoked, releasing resources they've acquired (if any).
3. All base classes of the object whose constructor threw will have their destructors invoked (since they
were fully constructed before the derived class constructor ran)
4. Further cleanup from the caller etc. will take place.

As a result, any resources that are managed by smart pointers or other RAII objects that are data members
of the object being destructed will indeed be cleaned up, but specialized code to do cleanup in the destructor
of the object won't fire.

Hope this helps!

answered Feb 3 at 1:01


templatetypedef
65.1k 10 143 288

Yes your step by step description cleared up everything! – newprogrammer Feb 3 at 1:13

feedback

These two statements don't contradict each other, but the first one has some unfortunate language. When
the construction of some object throws, it's deconstructor won't be called, but all objects owned by that object
will be destructed by their individual deconstructors.

So with RAII and smart pointers the destructors for any pointer members of an object will be called
independently of the destructor of the owing object. Raw pointers do not free the memory they point to and
have to be deleted manually. Should the constructor of the owning object throw raw pointers will not be freed.
This cannot happen with smart pointers.

answered Feb 3 at 1:00


honk
6,184 1 8 34

feedback

Not the answer you're looking for? Browse other questions tagged c++ exception

constructor raii or ask your own question.

2 of 2 21/12/12 10:21

You might also like