473,765 Members | 2,058 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

The "smart guarantee"?

I wanted to post this proposal on c.l.c++.m, but my news
server apparently does not support that group any more.

I propose a new class of exception safety known as the
"smart guarantee". Essentially, the smart guarantee
promises to clean up resources whose ownership is
passed into the function, for whatever defintion of "clean
up" is most appropriate for the resource passed.
Note that this is different from both the basic and the
strong guarantee.

According to David Abrahams, (here:
http://www.boost.org/more/generic_exception_safety.html)
the common guarantees are as follows:

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.

Now, one could be pedantic and say that the strong
guarantee doesn't really promise that the program state
will be "exactly" as it was before the operation started,
since there is now an exception object present in the
state which was not present before (if an exception is
thrown, of course). However, let us not dwell on that
pedantry, but a different one: what if the "operation" is
a function which receives ownership of a resource,
like so:

void foo(obj* p);

foo(new obj);

Now, before the function is called, a new object is
created on the heap. However, the only reference
to that object is bound to a parameter of foo(). So
technically, foo() is free to allow the last (and only)
reference to obj go out of scope, and still provide
the strong guarantee. If an exception is thrown, foo()
exits, and the object is still on the heap; hence, the
program state is preserved. Thus, foo() can be
strongly exception safe and leak a resource.

Clearly, most implementors of foo() will try to properly
dispose of p in the event of an exception. But now
foo() doesn't offer the strong guarantee, because if
an exception is thrown, the exit state will be different
from the entry state. However, such an implementation
of foo() still offers some measure of safety in the face
of exceptions, and foo() may provide the strong
guarantee for all of the state not including the
resources whose ownership was transferred into the
function.

I propose to call this level of safety the "smart
guarantee". It may seem like an obscure corner
case which does not deserve a name of its own,
because functions which take sole ownership of a
resource are not so common. I argue that if the
language receives fundamental support for move
semantics, then such functions may, in fact, become
more common; and thus this level of exception
safety may become more relevant.

I chose the name "smart" because that seems to
connote an awareness of resources or some type
of automatic management. Note that the smart
guarantee is somewhat orthogonal to the basic and
strong guarantee. So a function could provide the
basic guarantee for local state, and the smart
guarantee for ownership-transfer arguments.
Or, it could offer the strong guarantee for all
ownership-stable state, and the smart guarantee
for ownership-transfer state. It is perhaps useful to
call these situations the "smart basic guarantee"
and the "smart strong guarantee", respectively.
I think of the "smart guarantee" as the "smart
strong guarantee" by default.

To explicitly state that an operation does not
provide the smart guarantee, but does provide
one of the other guarantees, I would say that it
provides the "simple basic" or "simple strong"
guarantee. By default, "basic guarantee" and
"strong guarantee" should mean the simple
versions.

Comments are welcome.

Dave

Jul 19 '05 #1
14 2682
After some consideration, I realized that perhaps I
misunderstood the intended meaning of the basic
guarantee, and that most of what I suggest for the
smart guarantee is, in fact, covered by the basic
guarantee. However, I still maintain that there is a
middle ground between the basic and the strong
guarantee which should still be called the "smart
guarantee". But I no longer believe it is orthogonal
to the other guarantees. Rather, I believe it
occupies a point on the ladder of exception safety.

Consider a member or friend function which takes
ownership of an external resource:

class foo
{
// ...
public:
foo(obj* p)
{
try
{
some_init(p); // might throw
}
catch (...)
{
delete p;
}
}
void acquire(obj* p)
{
foo(p).swap(*th is);
}
void swap(foo& f); // nothrow
};

Now, acquire() provides the basic guarantee,
because foo's invariants are preserved, and p
is not leaked if foo(p) throws. However, acquire()
provides *more* than the basic guarantee,
because more than the invariants are preserved.
In fact, the entire state of foo is preserved. And
yet, acquire() provides *less* than the strong
guarantee, because it does not preserve the entire
program state (because it deletes p).

I contend that this level of safety is useful to identify,
because it is analogous to the strong guarantee
while not being the strong guarantee. You know
that foo's state is preserved, even if the external
state is not, and that can be a useful piece of
information in analyzing foo's behaviour in the
presence of exceptions.

Dave

Jul 19 '05 #2
David B. Held wrote in news:bj******** **@news.astound .net:

I wanted to post this proposal on c.l.c++.m, but my news
server apparently does not support that group any more.


X-Post added.

http://groups.google.co.uk/groups?gr...B%2B.moderated

Additionally here are a number of newsservers that will give you
readonly access I found allnews.readfre enews.net here:
http://freenews.maxbaud.net/newspage...ate=2003-09-05
some apparently allow posting but I didn't check if any carry
c.l.c++.m.
After some consideration, I realized that perhaps I
misunderstood the intended meaning of the basic
guarantee, and that most of what I suggest for the
smart guarantee is, in fact, covered by the basic
guarantee. However, I still maintain that there is a
middle ground between the basic and the strong
guarantee which should still be called the "smart
guarantee". But I no longer believe it is orthogonal
to the other guarantees. Rather, I believe it
occupies a point on the ladder of exception safety.

Consider a member or friend function which takes
ownership of an external resource:

class foo
{
// ...
public:
foo(obj* p)
{
try
{
some_init(p); // might throw
}
catch (...)
{
delete p;
}
}
void acquire(obj* p)
{
foo(p).swap(*th is);
}
void swap(foo& f); // nothrow
};

Now, acquire() provides the basic guarantee,
because foo's invariants are preserved, and p
is not leaked if foo(p) throws. However, acquire()
provides *more* than the basic guarantee,
because more than the invariants are preserved.
In fact, the entire state of foo is preserved.
Couldn't this be expressed as the the basic gaurantee +
entire state is invariant?
And
yet, acquire() provides *less* than the strong
guarantee, because it does not preserve the entire
program state (because it deletes p).

I contend that this level of safety is useful to identify,
because it is analogous to the strong guarantee
while not being the strong guarantee. You know
that foo's state is preserved, even if the external
state is not, and that can be a useful piece of
information in analyzing foo's behaviour in the
presence of exceptions.


What you need here is an example of a client of this
new guarantee, the problem I see is that the service is
offering to preserve its own state but not the clients.
As a client I don't think I'd have any use for that.

Rob.
--
http://www.victim-prime.dsl.pipex.com/

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.m oderated. First time posters: Do this! ]
Jul 19 '05 #3
"David B. Held" <dh***@codelogi cconsulting.com > writes:
Consider a member or friend function which takes
ownership of an external resource:

class foo
{
// ...
public:
foo(obj* p)
{
try
{
some_init(p); // might throw
}
catch (...)
{
delete p;
}
}
void acquire(obj* p)
{
foo(p).swap(*th is);
}
void swap(foo& f); // nothrow
};

Now, acquire() provides the basic guarantee,
because foo's invariants are preserved, and p
is not leaked if foo(p) throws. However, acquire()
provides *more* than the basic guarantee,
because more than the invariants are preserved.
In fact, the entire state of foo is preserved. And
yet, acquire() provides *less* than the strong
guarantee, because it does not preserve the entire
program state (because it deletes p).

I contend that this level of safety is useful to identify,
That is really the key question. There's not actually a "ladder" of
exception safety distinctions: it's a lattice. For example, you could
imagine a similar guarantee which says that *this might change if an
exception is thrown, but none of the arguments will be modified (in
addition to the basic guarantee of course). There are an infinite
number of other such distinctions.

But you've put your finger on it: is your guarantee really useful? I
chose to name the particular distinctions I did because they *were*
useful for reasoning about program correctness. How would you use
your guarantee in program design?
because it is analogous to the strong guarantee
while not being the strong guarantee.
That, in itself, does *not* make it useful. The guarantee I invented
above can make the same claims about being similar to the strong
guarantee yet I've never heard of anyone using or wanting it. I
could come up with any number of others.

In fact, why should *this be special? It's an argument like all the
others, except that it's "hidden".
You know that foo's state is preserved, even if the external state
is not, and that can be a useful piece of information in analyzing
foo's behaviour in the presence of exceptions.


Anything *could* be useful, but the proof is in the pudding.
Distinctions are useful in proportion to their starkness. If we
labelled every point in the spectrum we would have a wide array of
terms, but I claim it would leave us less powerful to identify program
behaviors, not more.

--
Dave Abrahams
Boost Consulting
www.boost-consulting.com
Jul 19 '05 #4
"David Abrahams" <da**@boost-consulting.com> wrote in message
news:ul******** ***@boost-consulting.com. ..
"David B. Held" <dh***@codelogi cconsulting.com > writes:
[...]
That is really the key question. There's not actually a
"ladder" of exception safety distinctions: it's a lattice.
The set of all possible exception safety rules is a lattice,
but the "known" rules form a non-decreasing hierarchy
of state integrity. The basic guarantee only promises that
in the event of an exception, state will be valid. The smart
guarantee says that state will be known, and most of it
will be unchanged. The strong and nothrow guarantee
say that all state will be unchanged.
For example, you could imagine a similar guarantee
which says that *this might change if an exception is
thrown, but none of the arguments will be modified
(in addition to the basic guarantee of course).
Yes, but can you cite one non-contrived instance in which
this guarantee offers something useful?
There are an infinite number of other such distinctions.
And most of the others are not useful, as you say below.
But you've put your finger on it: is your guarantee really
useful? I chose to name the particular distinctions I did
because they *were* useful for reasoning about
program correctness. How would you use your
guarantee in program design?
Let's use your example, but tweak it a bit. Instead of using
std::set, let's say we have a set container that uses pointer semantics, and
that it takes ownership of the objects put
into it. Furthermore, ptr_set::insert () gives the smart
guarantee:

template <class T>
class SearchableStack
{
public:
void push(T* t); // O(log n)
void pop(); // O(log n)
bool contains(T* t) const; // O(log n)
T* top() const; // O(1)
private:
ptr_set<T> set_impl;
std::list<ptr_s etset<T>::itera tor> list_impl;
};

/* 01 */ template <class T>
/* 02 */ void SearchableStack <T>::push(T* t)
/* 03 */ {
/* 04 */ ptr_set<T>::ite rator i = set_impl.insert (t);
/* 05 */ try
/* 06 */ {
/* 07 */ list_impl.push_ back(i);
/* 08 */ }
/* 09 */ catch(...)
/* 10 */ {
/* 11 */ set_impl.erase( i);
/* 12 */ throw;
/* 13 */ }
/* 14 */ }

The analysis would be the same as with your example
except for line 4. Not only do we want ptr_set::insert ()
to not change the set if it fails, we also want it to clean
up t as well, so we can write code like so:

SearchableStack <obj> s;
s.push(new obj);
because it is analogous to the strong guarantee
while not being the strong guarantee.


That, in itself, does *not* make it useful. The guarantee
I invented above can make the same claims about
being similar to the strong guarantee yet I've never
heard of anyone using or wanting it. I could come up
with any number of others.


Yes, but your example is not similar to the strong
guarantee in a useful way. My point is that the smart
guarantee is similar to the strong guarantee for all of
the state that you *wish* to be preserved, and only
violates transaction semantics to fulfill the constraint
that no resources are leaked. Since one does not need
to modify *this to prevent resource leakage, such a
property would not seem desirable.
In fact, why should *this be special? It's an argument
like all the others, except that it's "hidden".
I don't think *this is particularly special. What *is* special
is resources being bound to a function parameter with
no other references. That is the case that merits special
attention, IMO.
[...]
Anything *could* be useful, but the proof is in the
pudding. Distinctions are useful in proportion to their
starkness. If we labelled every point in the spectrum
we would have a wide array of terms, but I claim it
would leave us less powerful to identify program
behaviors, not more.


True enough. And like I said before, ownership transfer
may be rare enough that this distinction is not that
useful. I can't list a bunch of use cases where the
smart guarantee is an important part of exception safety
analysis. But I think it does address what seems to be
a flaw, or at least, a peculiarity, of the strong guarantee,
without inventing new exception guidelines arbitrarily.

Dave

Jul 19 '05 #5

"David B. Held" wrote:
[...]
Now, one could be pedantic and say that the strong
guarantee doesn't really promise that the program state
will be "exactly" as it was before the operation started,
since there is now an exception object present in the
state which was not present before (if an exception is
thrown, of course). However, let us not dwell on that
pedantry, but a different one: what if the "operation" is
a function which receives ownership of a resource,
like so:

void foo(obj* p);


then the "smart way" to tell the world about such incredible
peculiarity is nothing but just-do-it-like-so:

void foo(std::auto_p tr<obj> p);

Oder?

regards,
alexander.
Jul 19 '05 #6
"Rob Williscroft" <rt*@freenet.RE MOVE.co.uk> wrote in message
news:Xn******** *************** ***********@195 .129.110.131...
[...]
X-Post added.
Thanks.
[...]
Couldn't this be expressed as the the basic gaurantee +
entire state is invariant?
Yes, but I think that it occurs often enough that it deserves
its own name.
[...]
What you need here is an example of a client of this
new guarantee, the problem I see is that the service is
offering to preserve its own state but not the clients.
As a client I don't think I'd have any use for that.


Here is the motivating example:

void bar()
{
some_smart_ptr p(new obj);
// do stuff
}

Have you ever written code like this before? In this case,
you almost certainly don't want some_smart_ptr to
preserve your state, because you are giving away your
only reference to obj. Here is a perfect example of the
strong guarantee being "more safe" than you really
want. It should be obvious that you really do want the
function (in this case, and probably most, a c'tor) to
modify your state (by deleting your object) in the case of
an exception, but you also want it to provide the strong
guarantee for the rest of the state. So the guarantee
*does* preserve the client's state *whose ownership
is not transferred into the function*. The only state that
the guarantee says it will modify is exactly that state
which you would want it to modify anyway, which is
ownership-transferred resources. Otherwise, it is the
same as the strong guarantee.

For example, if you had this instead:

void baz()
{
a_deleter d;
some_smart_ptr p(new obj, d);
// do other stuff
}

the smart guarantee would say that d is unchanged in
the event of an exception, even if a non-const & to d is
passed in (for whatever reason). That's because
ownership of d is not being transferred into the function.

Dave


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.m oderated. First time posters: Do this! ]
Jul 19 '05 #7
"Alexander Terekhov" <te******@web.d e> wrote in message
news:3F******** *******@web.de. ..
[...]
then the "smart way" to tell the world about such
incredible peculiarity is nothing but just-do-it-like-so:

void foo(std::auto_p tr<obj> p);


Ah, but what if foo() is none other than
auto_ptr::auto_ ptr(T* p), or some other resource wrapper
c'tor? And if it's so peculiar, why do we have auto_ptr?

Dave

Jul 19 '05 #8

"David B. Held" wrote:

"Alexander Terekhov" <te******@web.d e> wrote in message
news:3F******** *******@web.de. ..
[...]
then the "smart way" to tell the world about such
incredible peculiarity is nothing but just-do-it-like-so:

void foo(std::auto_p tr<obj> p);
Ah, but what if foo() is none other than
auto_ptr::auto_ ptr(T* p),


That thing is throw()-nothing.
or some other resource wrapper c'tor?
http://groups.google.com/groups?selm...A16E4%40web.de
And if it's so peculiar, why do we have auto_ptr?


Irony aside, teleportation, you know.

http://www.research.ibm.com/quantuminfo/teleportation

regards,
alexander.
Jul 19 '05 #9
David B. Held wrote in news:bj******** **@news.astound .net:
"Rob Williscroft" <rt*@freenet.RE MOVE.co.uk> wrote in message
Couldn't this be expressed as the the basic gaurantee +
entire state is invariant?


Yes, but I think that it occurs often enough that it deserves
its own name.


I think it already has (kind of), see below.

[snip]
Here is the motivating example:

void bar()
{
some_smart_ptr p(new obj);
// do stuff
}

Have you ever written code like this before? In this case,
you almost certainly don't want some_smart_ptr to
preserve your state, because you are giving away your
only reference to obj. Here is a perfect example of the
strong guarantee being "more safe" than you really
want. It should be obvious that you really do want the
function (in this case, and probably most, a c'tor) to
modify your state (by deleting your object) in the case of
an exception, but you also want it to provide the strong
guarantee for the rest of the state.
Its the bit were you say "(by deleting your object)", Where I just
don't see it that way, once the paramiter has been succesfully
passed it belong's to the state of the function or ctor.
So the guarantee
*does* preserve the client's state *whose ownership
is not transferred into the function*. The only state that
the guarantee says it will modify is exactly that state
which you would want it to modify anyway, which is
ownership-transferred resources. Otherwise, it is the
same as the strong guarantee.

For example, if you had this instead:

void baz()
{
a_deleter d;
some_smart_ptr p(new obj, d);
// do other stuff
}

the smart guarantee would say that d is unchanged in
the event of an exception, even if a non-const & to d is
passed in (for whatever reason). That's because
ownership of d is not being transferred into the function.


This seems to be about RAII intialization and who takes
responsibility for the (or any) exception guarantees eg:

void client_responsi ble()
{
std::auto_ptr< obj > p( new obj );
server( p.get() );
p.release();
}

server_responsa ble would be your example and then there's:

void its_a_contract( )
{
std::auto_ptr< obj > temp( new obj )
server( temp );
}

Note that both client_reponsib le() and its_a_contract( ) can be
adapted to a server() taking multiple resources but:

void wont_work()
{
server( new obj, new obj );
}

can't. If either of the new obj expressions throw's the the other
leaks.

Which all means that whatever function or ctor we are talking about
that offers the Smart Guarantee is also a resource initializer,
wether we call it that or not.

From: http://www.boost.org/more/generic_exception_safety.html

<quote>
The basic guarantee: that the invariants of the component are
preserved, and no resources are leaked.
</quote>

I think that covers a RAII initializer. Though perhaps if it isn't
obvious (i.e. smart_ptr<> is obviously RAII) that RAII symantics
apply, we should document that the function/ctor is a RAII
initializer.

Rob.
--
http://www.victim-prime.dsl.pipex.com/

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.m oderated. First time posters: Do this! ]
Jul 19 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
12322
by: Martin Goldman | last post by:
Hello all, I've been struggling for a few days with the question of how to convert "smart" (curly) quotes into straight quotes. I tried playing with the htmlentities() function, but all that is doing is changing the smart quotes into nonsense characters. I also searched the web for quite a while and was unsuccessful in finding a solution. What puzzles me is that doing it the other way around is simple enough. For example, this works...
2
4271
by: Tim Hochberg | last post by:
During the recent, massive, painful Lisp-Python crossposting thread the evils of Python's whitespace based indentation were once again brought to light. Since Python' syntax is so incredibly brittle, and failure prone, it's amazing that we don't have more editor support for our feeble minds. To help reduce the severity of this crisis, I decided to take a whack at creating smart block copy and paste functionality. Anyway, I wrote some...
11
7039
by: Ron | last post by:
Hello, I'm having an aggravating time getting the "html" spewed by Word 2003 to display correctly in a webpage. The situation here is that the people creating the documents only know Word, and aren't very computer savvy. I created a system where they can save their Word documents as "html" and upload them to a certain directory, and the web page dynamically runs them through tidylib using the tidy extension to php4, thus causing the...
14
1840
by: Capstar | last post by:
Hi NG, I am developing a piece of software, which contains basicly one loop, which consinsts of 2 parts. Thos two parts are again basicly the same, but they deiffer in some variables. So I changed the variables from foo0 and foo1 to foo, so I can index them. This way I can run through the loop two times more, but switch the index between 0 and 1. This is pretty easy. I did it this way: int idx;
2
2379
by: BobAchgill | last post by:
Is there a way to let the User click on a button on a web site and have that download and install my prepackaged compressed data directory and place it nicely under my existing VB .Net Form application on the User's computer? Maybe another way of asking the question is. Can I build a smart .msi "data" installer that will when clicked on as "Run" on the web page will load into the desktop's memory ... find the location of my VB .Net Form...
5
2899
by: Noozer | last post by:
I'm looking for a "smart folder" program to run on my Windows XP machine. I'm not having any luck finding it and think the logic behind the program is pretty simple, but I'm not sure how I'd implement this. I've done some VB6 programming and dabbled in VS.Net. Can someone share some pointers in how I could implement the following? Basically, you drag a file to the "smart" folder and, depending on the type of file and settings for that...
0
9568
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9399
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
1
9957
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9835
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
6649
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5276
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
3924
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3532
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2806
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.