comp.lang.ada
 help / color / mirror / Atom feed
From: "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de>
Subject: Re: Quick question regarding limited type return syntax
Date: Sun, 3 Aug 2014 09:30:20 +0200
Date: 2014-08-03T09:30:20+02:00	[thread overview]
Message-ID: <vuqtsin4324j$.1qqhcwhbgnd21.dlg@40tude.net> (raw)
In-Reply-To: c450cgFq3u2U1@mid.individual.net

On Sat, 02 Aug 2014 23:35:34 +0300, Niklas Holsti wrote:

> On 14-08-02 19:56 , Dmitry A. Kazakov wrote:
>> On Sat, 02 Aug 2014 10:34:53 -0400, Robert A Duff wrote:
>> 
>>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
>>>
>>>> On Sat, 02 Aug 2014 09:20:45 -0400, Robert A Duff wrote:
>>>>
>>>>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
>>>>>
>>>>>> ...Dispatching calls
>>>>>> through class-wide access discriminants upon initialization/finalization.
>>>>>
>>>>> Can you please give an example of what you mean?
>>>>
>>>> Components not discriminants. I had Rosen's trick in mind:
>>>>
>>>>    type T is ...
>>>>        Self : not null access T := T'Unchecked_Access;
>>>
>>> Sorry, I still don't get it.  I don't see any class-wide types or
>>> dispatching calls there.  Also, it's illegal as written (the Rosen trick
>>> is only allowed for limited types.)  Perhaps a complete compilable
>>> example would help illustrate the language anomaly you are talking
>>> about.
>> 
>> with Ada.Finalization;
>> with Ada.Text_IO;
>> procedure Test is
>>    package P is
>>       type T is new Ada.Finalization.Limited_Controlled with record
>>          Self : not null access T'Class := T'Unchecked_Access;
>>       end record;
>>       overriding procedure Initialize (X : in out T);
>>       procedure Foo (X : in out T) is null;
>>    end P;
>>    
>>    package body P is
>>       procedure Initialize (X : in out T) is
>>       begin
>>          X.Self.Foo;
>>       end Initialize;   
>>    end P;
>>    
>>    package Q is
>>       use P;
>>       type S is new T with record
>>          I : Integer;
>>       end record;
>>       overriding procedure Initialize (X : in out S);
>>       overriding procedure Foo (X : in out S);
>>    end Q;
>>    
>>    package body Q is
>>       procedure Initialize (X : in out S) is
>>       begin
>>          T (X).Initialize;
>>          X.I := 1;
>>       end Initialize;
>>       procedure Foo (X : in out S) is
>>       begin
>>          X.I := X.I + 1;
>>       end Foo;
>>    end Q;
>>    
>>    Y : Q.S;
>> begin
>>    Ada.Text_IO.Put_Line (Integer'Image (Y.I));
>> end Test;
> 
> (Dmitry, I find it quite annoying that you just dump this code on us
> without bothering to explain why you think it shows some problem in Ada.)

Sorry, but the problem was self-evident to me. Robert asked for a working
example so I scraped together one without much thinking.

> The code indeed accesses an uninitialized datum: when Y is initialized,
> Initialize (S) calls Initialize (T), which makes a dispatching call to
> Foo (S), which accesses the component S.I, which is not yet initialized.

The code prematurely dispatches on an not yet initialized object. Again, it
was evident that this would happen when having a class-wide accessible in
Initialize when the parent's Initialize is to be called at the beginning of
the derived type Initialize.

> The flow of control in the example is a bit sneaky, but the
> self-referring component T.Self is in no way essential to the
> sneakiness; the same could be achieved by simply making a redispatching
> call to Foo in Initialize(T).

Yes, but as you probably remember, re-dispatching is already damned as
inconsistent regardless initialization.

> There are many other ways to create even sneakier flow of control with
> even more obscure opportunities for accessing uninitialized data.

There is no safe way to do initialization in Ada because it is not properly
typed. You should not be able to dispatch until the class-wide instance is
fully initialized, but you can because types are broken.

> Perhaps you have some personal design and coding rules which would
> prevent access to uninitialized data except for the kind of code shown
> in the example? That is, perhaps the ability to write such code in Ada
> breaks the safety of your design and coding rules? Perhaps the rule is
> that the Initialize operation of a derived type should first call
> Initialize on the parent type, and only then initialize the components
> added in the derivation (the extension components)? That is not a bad
> rule, but combining it with (re-)dispatching calls to operations
> overridden in the derived type obviously invites errors of the kind
> shown in the example.

The problem is with the semantics of Initialize, with its types.

1. IF Initialize does the specific type THEN it cannot dispatch AND it must
be through before any derived type's Initialize.

2. IF Initialize does class-wide type THEN it can dispatch AND must be
called after derived type's initialization.

It is sometimes one, sometimes another, sometimes both. It is a mess. Note
that there is a similar problem with constraints (with type invariants,
more generally):

   type Not_Working is
       Ref : not null access Something;
   end record;

This does not work for the same reason. There is no constructor which would
see Not_Working.Ref not yet initialized (without the constraint, when type
invariant not in place). Compare this with a class-wide access component to
itself. There is no constructor of the type itself which would see it not
initialized.

In both cases there can be a second level initialization where the
offending component is fully operational. But it cannot be both. Both means
types broken.

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


  reply	other threads:[~2014-08-03  7:30 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-07-30 23:51 Quick question regarding limited type return syntax NiGHTS
2014-07-31  0:02 ` Adam Beneschan
2014-07-31  0:56   ` NiGHTS
2014-07-31  0:48 ` Shark8
2014-07-31  1:00   ` NiGHTS
2014-07-31  1:29     ` Adam Beneschan
2014-07-31  1:38       ` NiGHTS
2014-07-31  4:01         ` Shark8
2014-08-01  2:12       ` Randy Brukardt
2014-08-01  3:40         ` Shark8
2014-08-01  7:57         ` J-P. Rosen
2014-08-01 19:23           ` Randy Brukardt
2014-08-01 19:37             ` J-P. Rosen
2014-08-01 20:53             ` Shark8
2014-08-02  7:11               ` Niklas Holsti
2014-08-02  7:34                 ` Dmitry A. Kazakov
2014-08-02 13:20                   ` Robert A Duff
2014-08-02 13:44                     ` Dmitry A. Kazakov
2014-08-02 14:34                       ` Robert A Duff
2014-08-02 16:56                         ` Dmitry A. Kazakov
2014-08-02 20:35                           ` Niklas Holsti
2014-08-03  7:30                             ` Dmitry A. Kazakov [this message]
2014-08-04  9:24                               ` Niklas Holsti
2014-08-04 10:42                                 ` G.B.
2014-08-04 11:39                                   ` Peter Chapin
2014-08-04 17:49                                     ` Niklas Holsti
2014-08-04 11:36                                 ` Peter Chapin
2014-08-04 12:43                                 ` Dmitry A. Kazakov
2014-08-04 16:19                                   ` G.B.
2014-08-04 16:38                                     ` Dmitry A. Kazakov
2014-08-04 16:51                                       ` G.B.
2014-08-04 17:23                                         ` Dmitry A. Kazakov
2014-08-04 19:37                                   ` Niklas Holsti
2014-08-05  8:30                                     ` Dmitry A. Kazakov
2014-08-05 19:24                                       ` Randy Brukardt
2014-08-03 16:35                           ` Robert A Duff
2014-08-02  8:02               ` Jacob Sparre Andersen
2014-08-02 19:20                 ` Shark8
2014-08-03 16:07                   ` Default values (Was: Quick question regarding limited type return syntax) Jacob Sparre Andersen
2014-08-04 21:29                     ` Randy Brukardt
replies disabled

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