Re: Controlled types and exception safety



On Wed, 30 Nov 2005 14:57:07 +0100, Maciej Sobczak wrote:

> Let's say that I want to write a stack in Ada. Making it a Controlled
> type seems to be a good idea, so that we have hooks for initialization,
> adjusting and finalization. Let's say that I have two stack objects, X
> and Y:
>
> X, Y : Stack;
>
> These objects were populated with some data, so that each of them
> manages its own internal dynamic data structure.
> Now, I do this:
>
> X := Y;
>
> and the following happens (this is what I understand, please correct me
> if I'm wrong):
>
> 1. X is finalized. This allows me to clean up (free) its internal data.
> 2. Y is *shallow-copied* to X, so that in effect X and Y share their state.
> 3. X is adjusted. This allows me to duplicate its internal structure so
> that it becomes independent from Y.
>
> later:
> 4. Both X and Y are finalized. This allows me to clean up (free) their
> resources.
>
> For everything to work correctly it's important that two separate stack
> objects *never* share their internal dynamic data structure, otherwise
> bad things can happen. It would be also fine not to leak memory.
>
> 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."

> I think that the inherent problem comes from the fact that the
> finalization of X was forced *before* its adjustment.
> 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. In Ada's case copy-constructor
is defined as Bitwise copy + Adjust. It is an atomic operation. Which is
equivalently means that in general case you cannot define any reasonable
semantics for its partial completion.

> The "Ada way" looks like selling the house *before* looking for the new one.
>
> What do you do to avoid surprises?

Don't let exceptions propagate.

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
.



Relevant Pages

  • Re: tungsten contacts
    ... Use adjustable pliers ... so I am using the PBR tungsten contacts. ... I knew the leaf blades were in bad shape and one stack was missing ... I made backer blades out of old thicker blades I didn't need; ...
    (rec.games.pinball)
  • Re: Sabotaged PaXtest (was: Re: Patch 4/6 randomize the stack pointer)
    ... What you get this way is a nice, complicated NOP. ... not only a nop but also a likely crash given that i didn't adjust ... [saved EBP replaced with address of [fake EBP]] ... the stack, so it's a generic method in that regard as well. ...
    (Linux-Kernel)
  • Re: 2.6.12-rc3 OOPS in vanilla source (once more)
    ... > - Do we need to adjust that initial ... esp0 indicates the start of the stack and ... what will be copied onto the stack so it makes even more sense to make ... problem as the traced child is scheduled away before the parent ...
    (Linux-Kernel)
  • Re: Controlled types and exception safety
    ... error happened that resulted in raising 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." ... 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. ... void operator=(const Stack &other) ...
    (comp.lang.ada)