comp.lang.ada
 help / color / mirror / Atom feed
From: Maciej Sobczak <no.spam@no.spam.com>
Subject: Re: Controlled types and exception safety
Date: Wed, 30 Nov 2005 17:19:23 +0100
Date: 2005-11-30T17:19:23+01:00	[thread overview]
Message-ID: <dmkjea$5o4$1@sunnews.cern.ch> (raw)
In-Reply-To: <he6790lx2j0a$.1xbozsrrw49xj$.dlg@40tude.net>

Dmitry A. Kazakov wrote:

>>Now, the interesting part: let's say that during adjustment (3.) some 
>>error happened (like low memory condition or whatever) that resulted in 
>>raising an exception
> 
> ARM 7.6.1 reads: "It is a bounded error for a call on Finalize or Adjust to
> propagate an exception.
> [...]
> For an Adjust invoked as part of an assignment operation, any other
> adjustments due to be performed are performed, and then Program_Error is
> raised."

OK, that brings some light, but does not solve my problem. :)

>>The canonical C++ way is to *first* make a copy of new value (because 
>>this is when errors might occur, so that even if they occur, there was 
>>no change in the destination object) and *then* inject the duplicate 
>>into the destination object, getting rid of its old state (and this is 
>>assumed to be nothrow).
> 
> Here the semantics of "copy", "inject", "duplicate" is ill-defined. In
> general, you can copy a set of bits, but you cannot an object without
> defining it in the terms copy-constructor.

When I said "copy" above (C++), I meant create a new object as a copy. 
This involves copy constructor. The point is that this new object is 
*separate* from the destination object (from what's on the left side of 
assignment operator), so even if there are errors, they do not influence 
any of the two objects which were originally involved. After this new 
helper object is constructed (which means: *successfully* constructed), 
it's "injected" in the destination object by means of swapping the bowels.
It looks like this:

class Stack
{
public:
     // other stuff, including copy constructor
     // ...

     // assignment operator with strong guarantee
     void operator=(const Stack &other)
     {
         Stack temp(other);  // this can fail, but that does not
                             // influence the "this" object

         swap(other);        // exchange of bowels (cannot fail)

                             // temp is cleaned up (cannot fail)
     }

private:
     // bowels
     // ...

     void swap(Stack &other)
     {
         // exchange bowels with the other Stack
         // this never fails if bowels involve only
         // fundamental types or components that
         // themselves have nothrow swap
     }
};

This idiom is very effective.

> In Ada's case copy-constructor
> is defined as Bitwise copy + Adjust.

The assignment is defined as Finalize + Bitwise copy + Adjust.
And it's the fact that Finalize comes first that bothers me.

> Which is
> equivalently means that in general case you cannot define any reasonable
> semantics for its partial completion.

Note that in the example above there is no "partial completion". On the 
contrary - either the operation completes successfully or it fails 
*wihout* modifying anything. Moreover, the scheme does not force me to 
ignore the error nor anything like this, I can let it go to the place 
where there's enough context to really handle it.

>>What do you do to avoid surprises?
> 
> Don't let exceptions propagate.

What do you mean by "don't propagate"? What if there is an exception 
that was raised by the run-time (like low memory condition) in the 
middle of adjusting the whole stack? What should I do with the part that 
was aleady adjusted (duplicated)? What should I do with the part that 
was not yet adjusted? Should I clean up what's already done and leave 
the destination stack as empty and shut the exception up, thus 
preventing the higer-level code from properly handling it?

Is it possible to have assignment with strong exception guarantee?


-- 
Maciej Sobczak : http://www.msobczak.com/
Programming    : http://www.msobczak.com/prog/



  reply	other threads:[~2005-11-30 16:19 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-11-30 13:57 Controlled types and exception safety Maciej Sobczak
2005-11-30 15:06 ` Dmitry A. Kazakov
2005-11-30 16:19   ` Maciej Sobczak [this message]
2005-12-01  0:05     ` Stephen Leake
2005-12-01  9:21     ` Dmitry A. Kazakov
2005-12-01 10:46       ` Maciej Sobczak
2005-12-01 15:08         ` Dmitry A. Kazakov
2005-12-02  4:17           ` Randy Brukardt
2005-12-02  9:29             ` Maciej Sobczak
2005-12-02 18:12               ` tmoran
2005-12-02 19:15                 ` Robert A Duff
2005-12-02 21:42                   ` tmoran
2005-12-06  9:00                     ` Maciej Sobczak
2005-12-06  9:50                       ` Dmitry A. Kazakov
2005-12-06 18:34                         ` Jeffrey R. Carter
2005-12-06 19:34                           ` Randy Brukardt
2005-12-06 21:20                             ` Dmitry A. Kazakov
2005-12-07  1:57                             ` Jeffrey R. Carter
2005-12-08  0:50                               ` Randy Brukardt
2005-12-08 19:37                                 ` Jeffrey R. Carter
2005-12-09  2:36                                   ` Randy Brukardt
2005-12-09  6:33                                     ` Jeffrey R. Carter
2005-12-09 20:35                                       ` Randy Brukardt
2005-12-10  7:53                                         ` Jeffrey R. Carter
2005-12-06 20:43                           ` Dmitry A. Kazakov
2005-12-07  2:00                             ` Jeffrey R. Carter
2005-12-07 10:01                               ` Dmitry A. Kazakov
2005-12-02 23:21             ` Robert A Duff
2005-11-30 17:46 ` Jean-Pierre Rosen
2005-11-30 21:02 ` Jeffrey R. Carter
2005-11-30 22:06   ` Björn Persson
2005-11-30 23:52     ` Randy Brukardt
2005-12-01  5:26     ` Jeffrey R. Carter
2005-12-02 23:51       ` Robert A Duff
2005-12-06 11:41   ` Peter C. Chapin
2005-12-06 12:50     ` Jean-Pierre Rosen
2005-12-06 13:06     ` Dmitry A. Kazakov
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox