c++ exception safety ali Çehreli [email protected]/turkcecpp/exception_safety.pdf ·...
TRANSCRIPT
![Page 1: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/1.jpg)
1
• Object lifetimes• Exceptions• RAII idiom• Smart pointers• Exception safety
C++ Exception Safety
Ali Çehreli
![Page 2: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/2.jpg)
2
Resources●Guru of the Week puzzles by Herb Sutter (archived at GotW.ca)●“Exceptional C++” books by Herb Sutter, which are based on the GotW●For a family of smart pointers: boost.org●For policybased smart pointers (and others): Andrei Alexandrescu's Loki library and his book “Modern C++ Design”
![Page 3: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/3.jpg)
3
Types of objects and their lifetimes
Automatic object: Lifetime is determined by the compiler; local objects, class members, temporary objects
Dynamic object: Lifetime is determined by the programmer; starts with new and ends with delete
Static object: Lifetime is determined by the compiler; ignored in this talk
![Page 4: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/4.jpg)
4
Automatic and dynamic objects
void foo(){ A a0;
D * d = new D; // dynamic
{ A a1; } // < a1 ends automatically
} // < a0 ends automatically
![Page 5: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/5.jpg)
5
Object Construction Stepsby the compiler
1) Construct virtual bases2) Construct other bases3) Initialize members in the order that they were defined4) Execute constructor body
![Page 6: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/6.jpg)
6
Object Destruction Stepsby the compiler
1) Execute the destructor body2) Destroy members and bases in the reverse order of construction
Note: Destructors of fundamental types are thought to be “empty”, i.e. ints are not “finalized” with any special value, and plain pointers don't delete the objects that they point to
![Page 7: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/7.jpg)
7
When Construction Fails,the compiler...
1) destroys all that is constructed so far, in the reverse order2) if the object was being “new'ed”, returns the memory that was allocated for the object
Note: The destructor of this object is not called.
![Page 8: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/8.jpg)
8
An object is not an object ...
... unless it's fully constructed...
class MyClass{ /* ... */
MyClass(/* ... */)
: /* base and member initializations */
{ /* further construction */
} // < only now an object};
![Page 9: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/9.jpg)
9
Exceptionsare ...a) only for important errors?b) for any error?c) for anything that's out of the ordinary?
● try to do something● an error may be thrown,● which some scope may catch.
Unwinding the program stack: exiting scopes recursively until a scope catches that type of exception; automatic objects are destructed as usual
![Page 10: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/10.jpg)
10
Stack Unwinding
If another exception is thrown during stack unwinding, meaning that an exception is already in flight; the program will abort.
Guideline: Never allow exceptions escape from destructors.
![Page 11: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/11.jpg)
11
A try/catch examplevoid foo(){ try { do_something(); possibly_not_executed(); } catch (const SomeTypeOfError & error) {
/* error handling */ }}
void do_something(){ if (some_condition) { throw SomeTypeOfError(); }
possibly_not_executed_either();}
![Page 12: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/12.jpg)
12
A safe way of managing resources in Cint bar(Resource ** in_out){ int err = 0; Resource * r0 = NULL; Resource * r1 = NULL;
err = allocate_resource(&r0); if (err) goto finally;
err = allocate_resource(&r1); if (err) goto finally;
/* use r0 and r1 */
if (err) goto finally;
/* transfer ownership */ *in_out = r0; r0 = NULL;
finally:
deallocate_resource(&r1); deallocate_resource(&r0);
return err;}
![Page 13: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/13.jpg)
13
A safe way of managing resources in Cint bar(Resource ** in_out){ int err = 0; Resource * r0 = NULL; Resource * r1 = NULL;
err = allocate_resource(&r0); if (err) goto finally;
err = allocate_resource(&r1); if (err) goto finally;
/* use r0 and r1 */
if (err) goto finally;
/* transfer ownership */ *in_out = r0; r0 = NULL;
finally:
deallocate_resource(&r1); deallocate_resource(&r0);
return err;}
![Page 14: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/14.jpg)
14
A safe way of managing resources in Cint bar(Resource ** in_out){ int err = 0; Resource * r0 = NULL; Resource * r1 = NULL;
err = allocate_resource(&r0); if (err) goto finally;
err = allocate_resource(&r1); if (err) goto finally;
/* use r0 and r1 */
if (err) goto finally;
/* transfer ownership */ *in_out = r0; r0 = NULL;
finally:
deallocate_resource(&r1); deallocate_resource(&r0);
return err;}
![Page 15: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/15.jpg)
15
A safe way of managing resources in C++Resource bar(){
Resource r0(/* ... */); Resource r1(/* ... */);
/* use r0 and r1 */
/* transfer ownership */ return r0;
}
![Page 16: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/16.jpg)
16
Explicit resource deallocation ...
void foo(){ Resource * p = allocate(); /* ... */ deallocate(p); // < explicit}
![Page 17: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/17.jpg)
17
... is not guaranteed to work in C++.
void foo(){ Resource * p = allocate(); /* ... */ // may throw deallocate(p); // may not be executed}
![Page 18: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/18.jpg)
18
RAII idiom(Resource Acquisition Is Initialization)
deallocation is destruction deallocation belongs in the destructor
Guideline: No explicit deallocation in code; deallocation happens in the destructor of a managing class.
![Page 19: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/19.jpg)
19
RAII example
void foo_wishful(){ Resource * p = allocate(); /* ... */ // may throw deallocate(p); // may not be executed}
void foo_RAII(){ ResourceManager p(allocate()); /* ... */ // may throw; fine...}
![Page 20: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/20.jpg)
20
Smart pointers
● RAII objects that delete the objects that they own● Can be used almost seamlessly as plain pointers● May have additional smarts
![Page 21: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/21.jpg)
21
A smart pointer implementationclass SmartPointer{ MyType * ptr;
public:
explicit SmartPointer(MyType * p = 0) : ptr(p) {}
~SmartPointer() { delete ptr; }
};
SmartPointer p(new MyType());
![Page 22: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/22.jpg)
22
A smart pointer implementationclass SmartPointer{ MyType * ptr;
public:
explicit SmartPointer(MyType * p = 0) : ptr(p) {}
~SmartPointer() { delete ptr; }
MyType * get() const { return ptr; }
};
SmartPointer p(new MyType());
bar(p.get());
![Page 23: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/23.jpg)
23
A smart pointer implementationclass SmartPointer{ MyType * ptr;
public:
explicit SmartPointer(MyType * p = 0) : ptr(p) {}
~SmartPointer() { delete ptr; }
MyType * get() const { return ptr; } MyType & operator* () const { return *ptr; }
};
SmartPointer p(new MyType());
bar(p.get());
MyType & r = *p;r.i = 7;
![Page 24: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/24.jpg)
24
A smart pointer implementationclass SmartPointer{ MyType * ptr;
public:
explicit SmartPointer(MyType * p = 0) : ptr(p) {}
~SmartPointer() { delete ptr; }
MyType * get() const { return ptr; } MyType & operator* () const { return *ptr; } MyType * operator>() const { return ptr; }
};
SmartPointer p(new MyType());
bar(p.get());
MyType & r = *p;r.i = 7; p>i = 42;
![Page 25: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/25.jpg)
25
A smart pointer implementationclass SmartPointer{ MyType * ptr;
public:
explicit SmartPointer(MyType * p = 0) : ptr(p) {}
~SmartPointer() { delete ptr; }
MyType * get() const { return ptr; } MyType & operator* () const { return *ptr; } MyType * operator>() const { return ptr; } bool operator! () const { return ptr == 0; }
};
SmartPointer p(new MyType());
bar(p.get());
MyType & r = *p;r.i = 7; p>i = 42;
if (!p) { /* ... */}
![Page 26: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/26.jpg)
26
A smart pointer implementationclass SmartPointer{ MyType * ptr;
public:
explicit SmartPointer(MyType * p = 0) : ptr(p) {}
~SmartPointer() { delete ptr; }
MyType * get() const { return ptr; } MyType & operator* () const { return *ptr; } MyType * operator>() const { return ptr; } bool operator! () const { return ptr == 0; }
private:
SmartPointer(SmartPointer const &); SmartPointer & operator= (SmartPointer const &);};
SmartPointer p(new MyType());
bar(p.get());
MyType & r = *p;r.i = 7; p>i = 42;
if (!p) { /* ... */}
SmartPointer p1(p); // ERRORp2 = p0; // ERROR
![Page 27: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/27.jpg)
27
boost::scoped_ptr
#include <boost/scoped_ptr.hpp>
typedef boost::scoped_ptr<Animal> AnimalPtr;
void foo(){ AnimalPtr animal(new Cat);
animal>talk();
/* ... */
} // Cat is deleted here
![Page 28: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/28.jpg)
28
boost::shared_ptr
![Page 29: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/29.jpg)
29
boost::weak_ptr
![Page 30: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/30.jpg)
30
Object goes, boost::weak_ptr remains
![Page 31: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/31.jpg)
31
boost::intrusive_ptr
●The type must already have a possibly more efficient way of reference counting●The memory footprint is the same as the plain T*●Two free functions must be defined:
void intrusive_ptr_add_ref(T *);void intrusive_ptr_release(T *);
![Page 32: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/32.jpg)
32
boost::scoped_array
● Like boost::scoped_ptr but calls delete[]● Instead, consider std::vector<MySharedPtr>
![Page 33: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/33.jpg)
33
boost::shared_array
● Like boost::shared_ptr but calls delete[]● Instead, consider std::vector<MySharedPtr>
![Page 34: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/34.jpg)
34
std::auto_ptr(might have been named std::transfer_ptr
equally usefully)
● The object is owned by a single auto_ptr at a given time
● When copied or assigned, the ownership changes hand: destination is the new owner, source is “nulled”
● Can not be used in standard containers (e.g. vector)
![Page 35: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/35.jpg)
35
C++ Technical Report 1 added some of Boost's smart pointers to the C++ standard library
●std::tr1::shared_ptr●std::tr1::weak_ptr●others?
![Page 36: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/36.jpg)
36
boost::ptr_vector
●Owns the objects of the pointers●Calls delete individually for the pointers in the vector
![Page 37: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/37.jpg)
37
Some History
● 1994: Tom Cargill's challenge to the C++ community, Exception Handling: A False Sense of Security (“Not possible to write a strongly exception safe Stack class template!”)
● 1997: Herb Sutter's Guru of the Week #8 as the first complete solution after long discussions on comp.lang.c++.moderated newsgroup
![Page 38: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/38.jpg)
38
Tom Cargill's Challenge: Stack::pop() can not be made strongly exception safe if T's copy constructor throws
template <class T>class Stack{ int count_; T * stack_; /* ... */
public: void push(const T &);
T pop() { /* ... */
T result = stack_[count_ 1]; count_; return result; }};
![Page 39: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/39.jpg)
39
template <class T>class Stack{ int count_; T * stack_; /* ... */
public: void push(const T &);
T & top() { return stack_[count_ 1]; }
void pop() { count_; }};
An exceptionsafe Stack interface
Guideline: Design exceptionsafe interfaces
![Page 40: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/40.jpg)
40
The Rule of The Big Three
If you need to define at least one of
● the destructor● the copy constructor● the assignment operator
chances are, you need to at least declare the other(s) private.
![Page 41: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/41.jpg)
41
Destructive Sense of SecurityIs this class safe?
class WishfulManager : private boost::noncopyable{ One * one_; Two * two_;
public:
WishfulManager() : one_(new One()), two_(new Two()) { /* further construction */ }
~WishfulManager() { delete two_; delete one_; }};
![Page 42: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/42.jpg)
42
Destructive Sense of SecurityNot safe!
class WishfulManager : private boost::noncopyable{ One * one_; Two * two_;
public:
WishfulManager() : one_(new One()), two_(new Two()) < 1: new may throw, < 2: Two() may throw { /* further construction */ < 3: something else may throw }
~WishfulManager() { delete two_; delete one_; }};
![Page 43: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/43.jpg)
43
Same class, this time copyable and assignable.Is it safe now?
class DubiousManager{ OneManager one_; // Assume that copying and assigning these TwoManager two_; // objects are “safe” operations; so it is safe // to use their compilergenerated defaultspublic:
DubiousManager() : one_(new One()), two_(new Two()) { /* further construction */ }
// No destructor needed...
};
![Page 44: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/44.jpg)
44
It depends!Not safe at least if the members have regular
assignment semantics e.g. like std::stringclass DubiousManager{ std::string one_; std::string two_;
public:
DubiousManager() : one_(“one”), two_(“two”) { /* further construction */ }
// No destructor needed...
// This class may be left in a halfassigned state if assignment // of two_ fails in the default operator=}; // (one_ would be assigned but not two_)
![Page 45: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/45.jpg)
45
The Rule of The Big One
If the class has more than one member, you may need to at least declare
● the assignment operator
private.
![Page 46: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/46.jpg)
46
Broken Definition of operator=
class MyClass{
/* ... */
MyClass & operator= (const MyClass & other) { if (this != &other) { // destroy the current state of this // copy new state from the other < may throw; bad... } return *this; }
};
![Page 47: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/47.jpg)
47
New Canonical Definition of operator=class SafeManager{ OnePtr one_; TwoPtr two_; string three_;
/* ... */
SafeManager & operator= (const SafeManager & other) { SafeManager temp(other);// < try copying on the side first this>swap(temp); // < swap this state with the copy
return *this; } // < old state is released along with temp
// Does not throw void swap(SafeManager & other) { one_.swap(other.one_); two_.swap(other.two_); three_.swap(other.three_); }};
![Page 48: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/48.jpg)
48
Exception Safety Guarantees
Basic Guarantee: No resources leaked, object(s) are still usable (consistent but not necessarily predictable state)Strong Guarantee: Program state remains unchangedNothrow Guarantee: The function will not emit an exception (e.g. swap())
![Page 49: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/49.jpg)
49
Summary: Exception Safety Guidelines
●Never allow exceptions escape from destructors●Never deallocate explicitly in code (RAII)●Do the work on the side first, then modify state●Never make exception safety an afterthought●Prefer cohesion (top() and pop())
![Page 50: C++ Exception Safety Ali Çehreli acehreli@yahooacehreli.org/turkcecpp/exception_safety.pdf · 2009-03-18 · • Exception safety C++ Exception Safety Ali Çehreli acehreli@yahoo.com](https://reader030.vdocuments.site/reader030/viewer/2022040400/5e7185295e1754538d29d0de/html5/thumbnails/50.jpg)
50
Refresher: Smart Pointers
boost::scoped_ptr: simple resource guard; noncopyable
boost::shared_ptr: reference counted ownership
boost::weak_ptr: no ownership; observer of shared_ptr
std::auto_ptr: transfer of ownership
etc...