comp.lang.ada
 help / color / mirror / Atom feed
From: Robert A Duff <bobduff@shell01.TheWorld.com>
Subject: Re: Why is the destructor called multiple times after I declare an object?
Date: Wed, 13 Jan 2016 11:03:24 -0500
Date: 2016-01-13T11:03:24-05:00	[thread overview]
Message-ID: <wccd1t5jwkz.fsf@shell01.TheWorld.com> (raw)
In-Reply-To: n75214$1ata$1@gioia.aioe.org

"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:

> It is rather a useless definition, because it would apply to the objects
> returned by-copy as well. At some point *some* object created as a
> result of a call to the callee becomes the object of the caller.

No, nonlimited objects work differently.  Consider:

  package P is

     type Doubly_Linked_List;
     type Node_Ptr is access all Doubly_Linked_List;
     type Doubly_Linked_List is limited record
        Next, Prev: Node_Ptr;
        Payload: Integer;
     end record;

     function Empty_List return Doubly_Linked_List;

     Global: Node_Ptr;

  end P;

  package body P is

     function Empty_List return Doubly_Linked_List is
     begin
        return Result: aliased Doubly_Linked_List do
           Result.Next := Result'Unchecked_Access;
           Result.Prev := Result'Unchecked_Access;
           Global := Result'Unchecked_Access;
        end return;
     end Empty_List;

  end P;

  with Text_IO; use Text_IO;
  procedure P.Main is
     My_List: aliased Doubly_Linked_List := Empty_List;
  begin
     Put_Line(Boolean'(Global = My_List'Unchecked_Access)'Img);
     Put_Line(Boolean'(My_List.Next = My_List'Unchecked_Access)'Img);
     Put_Line(Boolean'(My_List.Prev = My_List'Unchecked_Access)'Img);
  end P.Main;

The example must print TRUE three times.  In Empty_List, we set three
pointers pointing to Result.  After the call they point to My_List.
That's because My_List and Result are the same object.

If the implementation chooses to put My_List at a different location
than Result, and copy Result into My_List, it would have to update
those pointers, which is not easy.  The intended implementation is
to make sure that My_List and Result are at the same address.
My_List is of known size, so it is allocated at the declaration,
and its address is passed to Empty_List, so it knows where
to put Result.  If the size were not known at the call site,
things would be more complicated -- it passes information about
where to allocate (on the stack, on the global heap, in some
user-defined storage pool, ...), and the function would
do the allocation once it knows the size, and passes the
address back to the caller.

If we erase "limited", then the example is illegal -- Result can't be
aliased.  If that were allowed, then all three pointers would be
dangling pointers, and the Put_Lines would all be erroneous.
That's because Result and My_List are NOT the same object
in the nonlimited case, and Result is gone by the time the
Put_Lines are executed.

> To my understanding Randy's definition tried to address this by claiming
> absence of intermediate objects (as a generalization of the notion of
> copying).
>
>> Note that this point has nothing to do with extended_return syntax.
>
> Right. Also neither and no definition will work ever. Whichever syntax
> "same" object cannot be "returned".

Two access values are "=" if and only if they designate the same
object.  See example above.  QED.

>> The RM doesn't define "location".  And the rules about 'Address are
>> pretty loose.  And GNAT is correct here.
>
> I didn't doubt it. The example was for the sake of argument. If RM
> attempted to define "same" location in a useful way that would make
> reasonable implementations impossible.

Agreed.

>> Now, now, that's just sniping.
>
> Yes, yes, I fired back at an attempt to evade discussion by the game of
> definitions. (:-))

;-)

- Bob

  parent reply	other threads:[~2016-01-13 16:03 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-01-11  1:37 Why is the destructor called multiple times after I declare an object? Andrew Shvets
2016-01-11  2:18 ` Jeffrey R. Carter
2016-01-11  3:35   ` Andrew Shvets
2016-01-11 17:02     ` Brian Drummond
2016-01-11 16:29   ` Brian Drummond
2016-01-11 17:20     ` Simon Wright
2016-01-11 18:17     ` Bob Duff
2016-01-11 21:10       ` Dmitry A. Kazakov
2016-01-11 23:44         ` Randy Brukardt
2016-01-12  9:33           ` Dmitry A. Kazakov
2016-01-12 20:21             ` Randy Brukardt
2016-01-12 21:05               ` Dmitry A. Kazakov
2016-01-13  0:02                 ` Robert A Duff
2016-01-13  8:31                   ` Dmitry A. Kazakov
2016-01-13  9:01                     ` Georg Bauhaus
2016-01-13 14:45                     ` J-P. Rosen
2016-01-13 20:09                       ` Dmitry A. Kazakov
2016-01-14  9:04                         ` J-P. Rosen
2016-01-14  9:47                           ` Dmitry A. Kazakov
2016-01-13 16:03                     ` Robert A Duff [this message]
2016-01-13 19:59                       ` Dmitry A. Kazakov
2016-01-14 10:04                         ` Georg Bauhaus
2016-01-14 13:42                           ` Dmitry A. Kazakov
2016-01-12 12:41       ` Brian Drummond
2016-01-13 20:18       ` Jacob Sparre Andersen
2016-01-14  1:31         ` Robert A Duff
2016-01-12  0:43     ` Jeffrey R. Carter
replies disabled

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