Re: Controlled types and exception safety



On Wed, 30 Nov 2005 17:19:23 +0100, Maciej Sobczak wrote:

> 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. :)

Which is not solvable. The real problem is that you cannot both look into
an atomic abstraction and pretend that this look is consistent with the
abstraction. The problem comes with user-defined constructors. The language
generated ones are composed out of parts which can be reversible, provided
the language designer knows how to do it. But a user-defined constructor is
irreversible, otherwise than by, again, a user-defined destructor. Now you
are sitting in a rocket, a user-defined constructor has just turned on the
ignition, and oops, you notice that you have left your hat at home...

>> 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),

1. This changes little. Consider an exception raised while construction of
the copy. The copy is corrupt. Both to destruct or to just deallocate it
could be wrong.

2. User-defined constructor as a concept is useless if I cannot construct
in-place. Consider construction of non-movable objects containing self
references or bound to definite memory locations.

>> 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.

Me too, but exception-safety is irrelevant to the issue. If Ada should ever
have user-defined constructors and assignment (because Ada.Finalization is
not), then I would really like to have an access to the left part of the
assignment. IMO, the model could be:

1. Compiler-generated assignment is generated as Finalize +
Copy-constructor.

2. User-defined assignment can override it. However, there are many tough
problems. The assignment should be able to change the constraints (i.e.
bounds, discriminants, tags.) It should be composable against aggregation.
It should have access to the left part, but also be able to override it
in-place.

AFAIK, there is no language which does it right.

>> 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.

No, as I tried to explain above, it just moves the problem to construction
of a temporal object.

>>>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?

For a user-defined assignment the answer is no, or it is a halting problem.
For generated assignments it depends on whether its components are
reversible.

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



Relevant Pages

  • Re: Controlled types and exception safety
    ... >> constructor throws/raises, the object is considered to be never created ... you'll have memory leaks and other such badness. ... > actually wish is to have access to the left side of assignment. ... Ada doesn't really have user-defined assignment; ...
    (comp.lang.ada)
  • Re: Ada Interfaces and the Liskov Substitution Principle
    ... You don't have to do anything to make assignment for access T'Class ... There is the tag, it exists before the object and comes from the type of. ... Following your argument destructor of X isn't dispatching either, ... A part of the constructor of T'Class is certainly dispatching. ...
    (comp.lang.ada)
  • Re: C# Language Proposal for out Parameters
    ... >> If the assignment isn't made because an exception has been thrown, ... inout semantics, not to mention reducing overall clarity of the code. ... The fundamental problem is that GetNewValue would ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: DbC & Exceptions & Style
    ... exception. ... Different ways the constructor can fail ... to avoid writing code that converts GUI data into objects, ... All domain objects must now provide a default constructor. ...
    (comp.object)
  • Re: is such exception handling approach good?
    ... There is nothing wrong with throwing from constructor. ... It may be a good design, it may not be a good design from user's point ... resource API to free-up the resource on exception. ... change something - that is not initialization. ...
    (microsoft.public.vc.language)