comp.lang.ada
 help / color / mirror / Atom feed
From: "Randy Brukardt" <randy@rrsoftware.com>
Subject: Re: Controlled types and exception safety
Date: Thu, 1 Dec 2005 22:17:20 -0600
Date: 2005-12-01T22:17:20-06:00	[thread overview]
Message-ID: <Ga2dnUXKGspEVBLenZ2dnUVZ_tGdnZ2d@megapath.net> (raw)
In-Reply-To: c5f58jf7dlvo.jwmx6q1b5l24$.dlg@40tude.net

"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message
news:c5f58jf7dlvo.jwmx6q1b5l24$.dlg@40tude.net...
> On Thu, 01 Dec 2005 11:46:42 +0100, Maciej Sobczak wrote:
...
> > This changes a lot. I *know* how to deal with exceptions in
> > constructors, especially if their only effect is to build structures in
> > memory (and that applies to Stack in particular). Note that when the
> > constructor throws/raises, the object is considered to be never created
> > and its destructor is therefore never called.
>
> I.e. whatever side effects the failed constructor has caused, they will
> persist. The problem is not in finalization of the target. The problem is
> in the system state = whether objects invariants hold between their
> construction and finalization.

Right. Such a constructor ought to clean up its mess before propagating an
exception. If it doesn't, you'll have memory leaks and other such badness.

> [...]
> > What's wrong with the example I provided in my previous post?
> [...]
> > Which is exactly what is needed. If it fails, it can be rolled-back
> > without touching the original left object.
>
> As I said, in my view it has little to do with exception safety. What you
> actually wish is to have access to the left side of assignment. Controlled
> types do not provide this functionality. End of story.

Right again. Ada doesn't really have user-defined assignment; if you
*really* need that you have to use a procedure.

And in any case, what you are asking for would be contrary to the efficiency
goals of Ada. You're saying that all assignment *have to be* made to
temporaries. I can imagine some language working that way, but it's
performance would be several times slower than C++. We have enough trouble
with people thinking Ada is slow as it is, without duplicating all of the
effort twice. There is a lot of words in the Ada standard specifically to
allow implementers to optimize (eliminating the assignment temporary, for
instance).

Ada's model is that a failed assignment leaves the target corrupt. You can
mitigate that, but not completely eliminate it. If that is unacceptable for
your application (and I can think of few for which that would be the case),
then you have to avoid ":=" (most likely by using a limited type). At least
Ada 200Y improves the support for limited types a lot, so that you no longer
have to give up fancy constructors, aggregates, and constants when you use
them.

In your example of a failed stack assignment, the Adjust routine ought to
clean up the mess if Storage_Error is raised, and leave the target Stack
empty. Is this ideal? Possibily not, but it hardly matters, because there is
no clean way to know what might or might not have been done when the
assignment fails (read 11.6 if you believe otherwise); recovery means
exiting out and rolling back far more than one object. (And there really is
no safe, portable recovery from out-of-memory conditions -- you can only
figure out what works with a specific compiler and target and do that.)

...
> > The difficult part is that in *all* cases that I've seen or written (in
> > C++), it was not possible to guarantee that the duplication of state can
> > be performed without errors. This certainly applies to all types that
> > have dynamic memory structures behind them, starting from innocent
> > unbounded string. Ada has unbounded string, recommended on this group in
> > various contexts. How does it dolve this problem? Does it?
>
> I think Randy has answered that.

Probably not specifically. Obviously it depends on the implementation. I
just looked at ours, and it does nothing at all to handle memory issues in
Adjust. That means that the object would fail the invariants after such an
assignment. (I didn't actually realize that; it would be better to null the
pointer in that case...) And presumably, it would eventually access through
a deallocated pointer. But that's all a correct (if unfriendly)
implementation of Ada, because the object is abnormal, and any access to it
is erroneous -- see 13.9.1. (Humm, this actually isn't as clear as it ought
to be; one could argue that Storage_Error isn't a "language-defined check"
(its not called that in 11.1(6)). But surely it is intended to be covered;
it's hard to imagine a case that is more likely to corrupt things than
running out of memory. And it is indexed as a check. So I apply Dewar's rule
[the Standard never says anything silly]. Anyway, sorry about the language
lawyer musings...)

Moral: don't touch the left-hand side of any assignment after it failed
raising an exception, other than to assign a new value to the *entire*
value. If you want some other semantics, don't fool yourself and others by
calling it ":="; use limited types and appropriate copying procedures.

                              Randy.






  reply	other threads:[~2005-12-02  4:17 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
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 [this message]
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