What Comes To Mind
Sunday, February 20, 2005
  Thinking about Exception Safety in C++
Thanks to David Abrahams, we have a framework to discuss the relative exception safety of C++ components. Quick reiteration:
# The basic guarantee: that the invariants of the component are preserved, and no resources are leaked.
# The strong guarantee: that the operation has either completed successfully or thrown an exception, leaving the program state exactly as it was before the operation started.
# The no-throw guarantee: that the operation will not throw an exception.

A corner case, that came up recently in discussion about shared_ptr<>, is how to describe the situation where the invariants of the component are preserved, the state of the component is what it was before, but the state of the program is not exactly as it was before the operation started.

shared_ptr<> potentially can throw an exception during construction. If it does, the pointer that it is constructed on is deleted (or the deleter called). This is important, as it prevents any resource leak. But it does mean that there is a change in the state of the program. Whatever the pointer is pointing to is gone. Does this mean that shared_ptr<> only provides the basic guarantee?

That would be unsatsifying.

The only way out of it that I see is that any attempt to observe the changed state would involve undefined behavior. And it would be the same undefined behavior, at that point in the code, if the operation did succeed.

Concrete, simple, case:

Widget * w = new Widget; // 1
// ... some more code
shared_ptr sp_w = shared_ptr(w); // 2
// ... yet more code.
w->widgetOp(); // 3


How could we arrive at 3 if an exception was thrown at 2? Only if 2 was inside a try block of some kind, which implies at least one block scope level difference between //1 and //2.

Which means that when that scope was exited, sp_w would have gone out of scope and been deleted, so that any reference to w at //3 would be invalid.

It seems to me that the program state in the strong guarantee must be one that is marked as being the beginning of a transaction by opening a try block. That this is necessary, although not sufficient for transactional behavior. Of course to accomplish this, each component must revert its state to the initial conditions, no component can know enough to revert the state of the entire program.
 

Saturday, February 05, 2005
  More house construction
This the outside, now



This is our new walk-in closet and bathroom



This is a panoramic picture of the bedroom

 

Tuesday, February 01, 2005
  We Have a Roof!
Not only a roof, a whole second floor up there! This picture is from Monday morning. Our contractor worked over the weekend to keep us from freezing (more) than we already were. To be fair, he warned us it was going to be like living in a war zone once the roof started to come off.


 

Random notes and stuff

My Photo
Name: Steve Downey
Archives
September 2004 / January 2005 / February 2005 / March 2005 / May 2005 / June 2005 / October 2005 / January 2006 / February 2006 / March 2006 / January 2007 / February 2007 / April 2007 / November 2007 / December 2007 / January 2008 / September 2008 / November 2008 / April 2009 / July 2009 /


Powered by Blogger

Subscribe to
Posts [Atom]