comp.lang.ada
 help / color / mirror / Atom feed
* GNAT - return by anonymous access
@ 2011-12-17 19:17 Simon Belmont
  2011-12-17 19:51 ` Simon Wright
                   ` (3 more replies)
  0 siblings, 4 replies; 19+ messages in thread
From: Simon Belmont @ 2011-12-17 19:17 UTC (permalink / raw)



This ostensibly simple program prints strange results, and i'm rapidly
losing faith in the GNAT compiler (GNAT GPL 20110428).  If anyone with
an alternative compiler can confirm or deny this output as spurious, I
would be much obliged.  In short, when the declaration of 'bar' is
commented out, the program behaves as i would expect (output is '42'),
but when bar is present, the output is much different (output is
'4409264').  Or, if my line of reasoning is mixed up and this is
actually the appropriate behavior, I would be grateful for any
explanation.

Thank you again

-sb

-- Unit 1
package test_package is
   type test_type (p_obj : access Integer) is limited private;
   function get return test_type;

private
   type test_type (p_obj : access Integer) is limited null record;

end test_package;

-- Unit 2
package body test_package is

   function get return test_type is
   begin
      return test_type'(p_obj => new Integer'(42));
   end get;

end test_package;

-- Unit 3
with test_package;
with Text_IO;

procedure test_driver is

   foo : test_package.test_type := test_package.get;

   -- Removed : '42' (expected)
   -- Present : '4409264'
   bar : access Integer := new Integer'(69);

begin

   Text_IO.Put_Line(foo.p_obj.all'img);

end test_driver;



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: GNAT - return by anonymous access
  2011-12-17 19:17 GNAT - return by anonymous access Simon Belmont
@ 2011-12-17 19:51 ` Simon Wright
  2011-12-18  9:08 ` Georg Bauhaus
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 19+ messages in thread
From: Simon Wright @ 2011-12-17 19:51 UTC (permalink / raw)


Simon Belmont <sbelmont700@gmail.com> writes:

> This ostensibly simple program prints strange results, and i'm rapidly
> losing faith in the GNAT compiler (GNAT GPL 20110428).  If anyone with
> an alternative compiler can confirm or deny this output as spurious, I
> would be much obliged.  In short, when the declaration of 'bar' is
> commented out, the program behaves as i would expect (output is '42'),
> but when bar is present, the output is much different (output is
> '4409264').  Or, if my line of reasoning is mixed up and this is
> actually the appropriate behavior, I would be grateful for any
> explanation.

This surely can't be correct behaviour.

Here, on Mac OS X (64-bit compilers), GNAT GPL 2011 prints 1 (0 if I
make Test_Type non-limited).

GCC 4.6.0 behaves as you expect.



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: GNAT - return by anonymous access
  2011-12-17 19:17 GNAT - return by anonymous access Simon Belmont
  2011-12-17 19:51 ` Simon Wright
@ 2011-12-18  9:08 ` Georg Bauhaus
  2011-12-19 23:46 ` Randy Brukardt
  2011-12-20 23:53 ` anon
  3 siblings, 0 replies; 19+ messages in thread
From: Georg Bauhaus @ 2011-12-18  9:08 UTC (permalink / raw)


On 17.12.11 20:17, Simon Belmont wrote:

> begin
>
>     Text_IO.Put_Line(foo.p_obj.all'img);
>
> end test_driver;

Only for completeness, it will be easier to test the program with
alternative compilers if implementation-defined attribute
'Img (introduced in GNAT for debugging with pragma Debug, if memory
serves) is replaced with standard Ada,

       Text_IO.Put_Line(Integer'Image(foo.p_obj.all));

This alone does not change the output to something expected here.
However,

    function get return test_type is
    begin
       --return  test_type'(p_obj => new Integer'(42));
       return result: test_type(p_obj => new Integer'(42));
    end get;

makes the program print 42. Maybe this is triggering some Ada 95
circuits for discriminant constraints?  (Note to self: collect
some statistics of GNAT failing in the presence of discriminants.)



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: GNAT - return by anonymous access
  2011-12-17 19:17 GNAT - return by anonymous access Simon Belmont
  2011-12-17 19:51 ` Simon Wright
  2011-12-18  9:08 ` Georg Bauhaus
@ 2011-12-19 23:46 ` Randy Brukardt
  2011-12-20  0:14   ` Shark8
  2011-12-20 23:53 ` anon
  3 siblings, 1 reply; 19+ messages in thread
From: Randy Brukardt @ 2011-12-19 23:46 UTC (permalink / raw)


"Simon Belmont" <sbelmont700@gmail.com> wrote in message 
news:784c67eb-a542-41b0-b23d-fca1234e56b2@n10g2000vbg.googlegroups.com...
>
> This ostensibly simple program prints strange results...
...
>   type test_type (p_obj : access Integer) is limited null record;
...
>   function get return test_type is
>   begin
>      return test_type'(p_obj => new Integer'(42));
>   end get;

You are creating a coextension here. The *language rules* for coextensions 
are full of bugs; we're fixing them virtually every ARG meeting. There is 
little hope for a compiler to get these right in the face of that, beyond 
which doing so is quite expensive.

IMHO, any use of an allocator for an anonymous access type is asking for 
trouble. There is no way to free the memory for such things, and the 
lifetime can easily be extended in various ways, so if the compiler tries 
using a properly local pool for the allocator you end up with a dangling 
poiner. Moreover, they appear to promise something that they cannot deliver 
(heap-based allocation).

Ada 2012 has a restriction No_Anonymous_Allocators; I recommend that all Ada 
programs include and obey this restriction. (Janus/Ada does this by default, 
because we never attempted to use the local pools that supposedly are 
required, and it is better to reject a program rather than implement it 
"wrong".)

                                                    Randy.





^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: GNAT - return by anonymous access
  2011-12-19 23:46 ` Randy Brukardt
@ 2011-12-20  0:14   ` Shark8
  2011-12-20 23:18     ` Randy Brukardt
  0 siblings, 1 reply; 19+ messages in thread
From: Shark8 @ 2011-12-20  0:14 UTC (permalink / raw)


On Dec 19, 5:46 pm, "Randy Brukardt" <ra...@rrsoftware.com> wrote:
> "Simon Belmont" <sbelmont...@gmail.com> wrote in message
>
> news:784c67eb-a542-41b0-b23d-fca1234e56b2@n10g2000vbg.googlegroups.com...
>
>
>
> > This ostensibly simple program prints strange results...
> ...
> >   type test_type (p_obj : access Integer) is limited null record;
> ...
> >   function get return test_type is
> >   begin
> >      return test_type'(p_obj => new Integer'(42));
> >   end get;
>
> You are creating a coextension here. The *language rules* for coextensions
> are full of bugs; we're fixing them virtually every ARG meeting. There is
> little hope for a compiler to get these right in the face of that, beyond
> which doing so is quite expensive.
>
> IMHO, any use of an allocator for an anonymous access type is asking for
> trouble. There is no way to free the memory for such things, and the
> lifetime can easily be extended in various ways, so if the compiler tries
> using a properly local pool for the allocator you end up with a dangling
> poiner. Moreover, they appear to promise something that they cannot deliver
> (heap-based allocation).
>
> Ada 2012 has a restriction No_Anonymous_Allocators; I recommend that all Ada
> programs include and obey this restriction. (Janus/Ada does this by default,
> because we never attempted to use the local pools that supposedly are
> required, and it is better to reject a program rather than implement it
> "wrong".)
>
>                                                     Randy.

Hm, so then are local pools useless? Or do they have their place?
I read some of the rational[e/ization] for them and it seems
reasonable, but I've not actually used them.



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: GNAT - return by anonymous access
  2011-12-20  0:14   ` Shark8
@ 2011-12-20 23:18     ` Randy Brukardt
  2011-12-21  0:44       ` Simon Belmont
  0 siblings, 1 reply; 19+ messages in thread
From: Randy Brukardt @ 2011-12-20 23:18 UTC (permalink / raw)


"Shark8" <onewingedshark@gmail.com> wrote in message 
news:b896b012-1f49-494c-a585-3d37a7c0965a@q9g2000yqe.googlegroups.com...

>Hm, so then are local pools useless? Or do they have their place?
>I read some of the rational[e/ization] for them and it seems
>reasonable, but I've not actually used them.

A local pool is fine, so long as it is tied to a local pool-specific access 
type. Using a pool (any pool!) with general access type is asking for 
trouble. And anonymous access types are general access types by definition.

It's best to do all of your allocation with a named pool-specific access 
type, and then (if necessary) convert the value to a more flexible general 
access type (including the anonymous ones). That way, you'll at least know 
how long the access value is supposed to live, and have a means of freeing 
it explicitly if needed.

Personally, I'd just avoid anonymous access types, but I'm not going to go 
so far as to recommend that (there are things that are hard to do any other 
way).

                                        Randy.





^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: GNAT - return by anonymous access
  2011-12-17 19:17 GNAT - return by anonymous access Simon Belmont
                   ` (2 preceding siblings ...)
  2011-12-19 23:46 ` Randy Brukardt
@ 2011-12-20 23:53 ` anon
  3 siblings, 0 replies; 19+ messages in thread
From: anon @ 2011-12-20 23:53 UTC (permalink / raw)


A corrected version, that works!

Just made a few changes in the code.

  First GNAT does not like the "access Integer", define a 
Integer_Access type.

  Second, "limited" was remove because of the error message  
"cannot initialize entities of limited type".

  Third, I use an "Use" Statement in "test_driver.adb" instead of 
using of "test_package.".


-- Unit 1
package test_package is

   type Integer_Access is access all Integer ;

   type test_type (p_obj : Integer_Access) is private;

   function get return test_type;

private
   type test_type (p_obj : Integer_Access) is null record ;

end test_package;


-- Unit 2
package body test_package is

   function get return test_type is
   begin
      return test_type ' ( p_obj => new Integer'(42) );
   end get;

end test_package;


-- Unit 3
with test_package;
with Text_IO;
use test_package;

procedure test_driver is

   foo : test_type := test_package.get;

   -- Removed : '42' (expected)
   -- Present : '4409264'
   bar : Integer_Access := new Integer'(69);

begin

   Text_IO.Put_Line(foo.p_obj.all'img);

end test_driver;



In <784c67eb-a542-41b0-b23d-fca1234e56b2@n10g2000vbg.googlegroups.com>, Simon Belmont <sbelmont700@gmail.com> writes:
>
>This ostensibly simple program prints strange results, and i'm rapidly
>losing faith in the GNAT compiler (GNAT GPL 20110428).  If anyone with
>an alternative compiler can confirm or deny this output as spurious, I
>would be much obliged.  In short, when the declaration of 'bar' is
>commented out, the program behaves as i would expect (output is '42'),
>but when bar is present, the output is much different (output is
>'4409264').  Or, if my line of reasoning is mixed up and this is
>actually the appropriate behavior, I would be grateful for any
>explanation.
>
>Thank you again
>
>-sb
>
>-- Unit 1
>package test_package is
>   type test_type (p_obj : access Integer) is limited private;
>   function get return test_type;
>
>private
>   type test_type (p_obj : access Integer) is limited null record;
>
>end test_package;
>
>-- Unit 2
>package body test_package is
>
>   function get return test_type is
>   begin
>      return test_type'(p_obj => new Integer'(42));
>   end get;
>
>end test_package;
>
>-- Unit 3
>with test_package;
>with Text_IO;
>
>procedure test_driver is
>
>   foo : test_package.test_type := test_package.get;
>
>   -- Removed : '42' (expected)
>   -- Present : '4409264'
>   bar : access Integer := new Integer'(69);
>
>begin
>
>   Text_IO.Put_Line(foo.p_obj.all'img);
>
>end test_driver;




^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: GNAT - return by anonymous access
  2011-12-20 23:18     ` Randy Brukardt
@ 2011-12-21  0:44       ` Simon Belmont
  2011-12-21  7:29         ` AdaMagica
  0 siblings, 1 reply; 19+ messages in thread
From: Simon Belmont @ 2011-12-21  0:44 UTC (permalink / raw)


On Dec 20, 6:18 pm, "Randy Brukardt" <ra...@rrsoftware.com> wrote:
>
> Personally, I'd just avoid anonymous access types, but I'm not going to go
> so far as to recommend that (there are things that are hard to do any other
> way).
>

It is my understanding that Ada05 has done away with 'return-by-
reference' in favor of 'return-by-anonymous-access', which would lead
me to believe that you would *have* to use them if you want to return
an allocated limited type.  Personally I am suspect of this method, as
it exposes the access value to the nefarious shenanigans other code
could potentially try (hence the original code that was testing ways
of protecting the value inside an object).  Are there other ways of
doing this that aren't so...dubious?



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: GNAT - return by anonymous access
  2011-12-21  0:44       ` Simon Belmont
@ 2011-12-21  7:29         ` AdaMagica
  2011-12-21 11:05           ` Georg Bauhaus
  2011-12-22  0:33           ` Simon Belmont
  0 siblings, 2 replies; 19+ messages in thread
From: AdaMagica @ 2011-12-21  7:29 UTC (permalink / raw)


On 21 Dez., 01:44, Simon Belmont <sbelmont...@gmail.com> wrote:
> It is my understanding that Ada05 has done away with 'return-by-
> reference' in favor of 'return-by-anonymous-access', which would lead
> me to believe that you would *have* to use them if you want to return
> an allocated limited type.

Hm, no, return-by-reference has been replaced by build-in-place.



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: GNAT - return by anonymous access
  2011-12-21  7:29         ` AdaMagica
@ 2011-12-21 11:05           ` Georg Bauhaus
  2011-12-21 11:43             ` AdaMagica
  2011-12-22  0:33           ` Simon Belmont
  1 sibling, 1 reply; 19+ messages in thread
From: Georg Bauhaus @ 2011-12-21 11:05 UTC (permalink / raw)


On 21.12.11 08:29, AdaMagica wrote:
> On 21 Dez., 01:44, Simon Belmont<sbelmont...@gmail.com>  wrote:
>> It is my understanding that Ada05 has done away with 'return-by-
>> reference' in favor of 'return-by-anonymous-access', which would lead
>> me to believe that you would *have* to use them if you want to return
>> an allocated limited type.
>
> Hm, no, return-by-reference has been replaced by build-in-place.

GNAT recommends to use a pointer, though, in one of its
error messages. Perhaps this should be changed so that
it suggests a construct like

   X := new Limited_Type'(Build_in_Place_Function);

?





^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: GNAT - return by anonymous access
  2011-12-21 11:05           ` Georg Bauhaus
@ 2011-12-21 11:43             ` AdaMagica
  2011-12-21 12:05               ` Georg Bauhaus
  0 siblings, 1 reply; 19+ messages in thread
From: AdaMagica @ 2011-12-21 11:43 UTC (permalink / raw)


On 21 Dez., 12:05, Georg Bauhaus <rm.dash-bauh...@futureapps.de>
wrote:
>    X := new Limited_Type'(Build_in_Place_Function);

declare
  X: Some_Limited_Type := Function_Call_or_Aggregate;  -- this is
built in place (no pointer in use)



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: GNAT - return by anonymous access
  2011-12-21 11:43             ` AdaMagica
@ 2011-12-21 12:05               ` Georg Bauhaus
  2011-12-22  0:33                 ` Randy Brukardt
  0 siblings, 1 reply; 19+ messages in thread
From: Georg Bauhaus @ 2011-12-21 12:05 UTC (permalink / raw)


On 21.12.11 12:43, AdaMagica wrote:
> On 21 Dez., 12:05, Georg Bauhaus<rm.dash-bauh...@futureapps.de>
> wrote:
>>     X := new Limited_Type'(Build_in_Place_Function);
>
> declare
>    X: Some_Limited_Type := Function_Call_or_Aggregate;  -- this is
> built in place (no pointer in use)

OP wanted to return an allocated object of limited type (which
is when GNAT issues its message). If there is a reason for doing
so (maybe allocating a global library level task at some nested
level), then what can be done without a redesign?

(Is everyone happy with dropping return-by-reference for limited
types? There was a use case for these. I guess it has not
disappeared, whatever difficulties implementers might have
encountered...)



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: GNAT - return by anonymous access
  2011-12-21  7:29         ` AdaMagica
  2011-12-21 11:05           ` Georg Bauhaus
@ 2011-12-22  0:33           ` Simon Belmont
  2011-12-22  7:11             ` Adam Beneschan
  1 sibling, 1 reply; 19+ messages in thread
From: Simon Belmont @ 2011-12-22  0:33 UTC (permalink / raw)


On Dec 21, 2:29 am, AdaMagica <christ-usch.gr...@t-online.de> wrote:
> Hm, no, return-by-reference has been replaced by build-in-place.

Building in place creates another object, does it not?  Changes to a
returned built in place type would not affect the original object.
Suppose I have a package with some internal object of a limited, not
necessarily allocated, but that has to get exposed to other units:

package body Sample is

  foo : Lim_Type_Ptr := -- ...stuff

  function Get return Lim_Type is
  begin
    return foo.all;
  end Sample;

The above code, which as I understand it would be legal Ada95 code,
doesn't return the actual object, but returns a pointer that the
compiler automatically dereferences behind the scenes.  The client
can't change, copy, or delete the object or the access value because
it cannot reference it.

In the Ada05 version, it would have to return a Lim_Type_Ptr (or,
equivilently, an access Lim_Type), and the client would have to
dereference it.  Now the client has free means to change, copy, and
deallocate the access value.  At best it works the same, and at worst
an errant programmer can wreak havoc.

I suppose my question is why?  No one seems to have a valid technical
reason for this change, other than returning-by-reference is
'unusual', which doesn't seem like nearly enough of a good reason to
take something that was working fine and make it more dangerous.

-sb




^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: GNAT - return by anonymous access
  2011-12-21 12:05               ` Georg Bauhaus
@ 2011-12-22  0:33                 ` Randy Brukardt
  0 siblings, 0 replies; 19+ messages in thread
From: Randy Brukardt @ 2011-12-22  0:33 UTC (permalink / raw)


"Georg Bauhaus" <rm.dash-bauhaus@futureapps.de> wrote in message 
news:4ef1cb93$0$7626$9b4e6d93@newsspool1.arcor-online.net...
...
> OP wanted to return an allocated object of limited type (which
> is when GNAT issues its message). If there is a reason for doing
> so (maybe allocating a global library level task at some nested
> level), then what can be done without a redesign?

A redesign is necessary, because what he is trying to do is not likely to 
work on any Ada compiler, and is certainly not going to be portable to other 
Ada compilers (because the language rules aren't consistent).

> (Is everyone happy with dropping return-by-reference for limited
> types? There was a use case for these. I guess it has not
> disappeared, whatever difficulties implementers might have
> encountered...)

We (the ARG) think that is you really need return-by-reference, you should 
write it explicitly using an access type. (And my preference is that access 
type is a pool-specific named access type, otherwise, you'll run into the 
sort of problems the OP did - the rules for anonymous types are a mess.) 
That is, your function should return an access value, not some other type 
where the by-reference nature is hidden (and causes all sort of problems in 
actual use).

Ada 95's rules caused huge problems when you had limited types. In Claw, the 
registry key type is limited, and the effort to create the predefined keys 
was insane: you couldn't declare constants, you could declare a function, 
but you couldn't return an aggregate, you couldn't return a local object, 
you could return a global object -- but that is where we started! -- these 
objects couldn't be constants, they couldn't be initialized with an 
aggregate (either in the declaration or in the package body). We had to 
resort to initializing them component-by-component in the package body - a 
hugely error-prone way of working. Luckily, these things hardly ever change, 
so it was a one-time pain in Claw -- in other circumstances it could be a 
real maintenance problem.

Ada 2005 added build-in-place to solve all of that. But for that to make 
sense, the old scheme had to go, thus we got rid of return-by-reference 
(which never made any sense in the first place).

                                             Randy.







^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: GNAT - return by anonymous access
  2011-12-22  0:33           ` Simon Belmont
@ 2011-12-22  7:11             ` Adam Beneschan
  2011-12-22 22:11               ` Simon Belmont
  0 siblings, 1 reply; 19+ messages in thread
From: Adam Beneschan @ 2011-12-22  7:11 UTC (permalink / raw)


On Dec 21, 4:33 pm, Simon Belmont <sbelmont...@gmail.com> wrote:
> On Dec 21, 2:29 am, AdaMagica <christ-usch.gr...@t-online.de> wrote:
>
> > Hm, no, return-by-reference has been replaced by build-in-place.
>
> Building in place creates another object, does it not?  Changes to a
> returned built in place type would not affect the original object.
> Suppose I have a package with some internal object of a limited, not
> necessarily allocated, but that has to get exposed to other units:
>
> package body Sample is
>
>   foo : Lim_Type_Ptr := -- ...stuff
>
>   function Get return Lim_Type is
>   begin
>     return foo.all;
>   end Sample;
>
> The above code, which as I understand it would be legal Ada95 code,
> doesn't return the actual object, but returns a pointer that the
> compiler automatically dereferences behind the scenes.  The client
> can't change, copy, or delete the object or the access value because
> it cannot reference it.
>
> In the Ada05 version, it would have to return a Lim_Type_Ptr (or,
> equivilently, an access Lim_Type), and the client would have to
> dereference it.  Now the client has free means to change, copy, and
> deallocate the access value.  At best it works the same, and at worst
> an errant programmer can wreak havoc.

I think this could be solved by declaring a private type (limited
private, if you prefer) to represent an "access" or "handle" or
"reference" to test_type.  It would be implemented as an access type,
basically, but the client wouldn't see it as an access type, so it
couldn't deallocate it, and if you make it limited private it couldn't
copy it either.  The only thing you lose is that since it's private,
you couldn't directly use it to access components of the accessed type
(test_type).  But in your example, test_type is private anyway, so
this isn't much of a loss, except for the ability to access the
discriminant p_obj, and you could provide a function to do that.


> I suppose my question is why?  No one seems to have a valid technical
> reason for this change, other than returning-by-reference is
> 'unusual', which doesn't seem like nearly enough of a good reason to
> take something that was working fine and make it more dangerous.

You might want to check out

http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ais/ai-10318.txt?rev=1.16

just to convince yourself that, yes, they *did* have plenty of valid
technical reasons.  Even if this is hard to follow, at least the fact
that they had as much discussion as they did should make it clear that
this wasn't something the ARG did just because they got drunk and felt
like changing something.

                             -- Adam



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: GNAT - return by anonymous access
  2011-12-22  7:11             ` Adam Beneschan
@ 2011-12-22 22:11               ` Simon Belmont
  2011-12-23  0:56                 ` Randy Brukardt
  0 siblings, 1 reply; 19+ messages in thread
From: Simon Belmont @ 2011-12-22 22:11 UTC (permalink / raw)


On Dec 22, 2:11 am, Adam Beneschan <a...@irvine.com> wrote:

> I think this could be solved by declaring a private type (limited
> private, if you prefer) to represent an "access" or "handle" or
> "reference" to test_type.
>

That's essentially the path I was taking, but it's doesn't scale well
(at all, really).  You essentially have to remake every primitive
operation of the original type for the new faux-access to forward the
calls so that anything useful could be done.  I guess on a case-by-
case basis that would work, but not in general.  And if you provide a
function to return the access type, then you are right back into the
same situation of having it exposed to potential grief.  It's too bad
access types can't be limited...

>
> You might want to check out
>
> http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ais/ai-10318.txt?rev=1.16
>

Thanks for that link, it was exactly the type of info i was interested
in.

-sb



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: GNAT - return by anonymous access
  2011-12-22 22:11               ` Simon Belmont
@ 2011-12-23  0:56                 ` Randy Brukardt
  2011-12-23 13:20                   ` Simon Belmont
  0 siblings, 1 reply; 19+ messages in thread
From: Randy Brukardt @ 2011-12-23  0:56 UTC (permalink / raw)


"Simon Belmont" <sbelmont700@gmail.com> wrote in message 
news:8a7d4dc1-69e5-479f-84a3-5c9c7bdd9aae@j10g2000vbe.googlegroups.com...
On Dec 22, 2:11 am, Adam Beneschan <a...@irvine.com> wrote:

>> I think this could be solved by declaring a private type (limited
>> private, if you prefer) to represent an "access" or "handle" or
>> "reference" to test_type.

>That's essentially the path I was taking, but it's doesn't scale well
>(at all, really).  You essentially have to remake every primitive
>operation of the original type for the new faux-access to forward the
>calls so that anything useful could be done.

You could use an Ada 2012 accessor (see 4.1.5 in the draft Ada 2012 RM, or 
AI05-0139-2). It seems that was what you were trying to do (since those 
depend on an access discriminant) -- but the key is, don't, under *ANY* 
circumstances, use an allocator for such a type. Initializing the 
discriminant with an existing object is fine. That's what you'd have to do 
in Ada 95, so I don't really understand why you suddenly changed to using an 
allocator in your Ada 2005 code.

The Ada 95 facility didn't give you any real protection against 
modification, so I don't quite see what you think was lost. But, anyway, use 
the accessor facility: it does give the right lifetime protections.

If you want more detail, I'll be happy to work up an example (but I'll be 
away over the holidays, so not until next week).

                                                     Randy.





^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: GNAT - return by anonymous access
  2011-12-23  0:56                 ` Randy Brukardt
@ 2011-12-23 13:20                   ` Simon Belmont
  2011-12-27 23:51                     ` Randy Brukardt
  0 siblings, 1 reply; 19+ messages in thread
From: Simon Belmont @ 2011-12-23 13:20 UTC (permalink / raw)


On Dec 22, 7:56 pm, "Randy Brukardt" <ra...@rrsoftware.com> wrote:
>
> You could use an Ada 2012 accessor (see 4.1.5 in the draft Ada 2012 RM, or
> AI05-0139-2). It seems that was what you were trying to do (since those
> depend on an access discriminant) -- but the key is, don't, under *ANY*
> circumstances, use an allocator for such a type. Initializing the
> discriminant with an existing object is fine. That's what you'd have to do
> in Ada 95, so I don't really understand why you suddenly changed to using an
> allocator in your Ada 2005 code.
>

Thank you for pointing out the 2012 construct; the endgame was
lifetime control, so that's the right tool for the job.  As far as
using the allocator in such a way, that was never the intention, just
a shortcut i used in a test that uncovered the bug about which I
originally posted before things got sidetracked.  However, it's good
to know that using a 'coextension' has such counter-intuitive
operation.  I assumed that it would be functionally equivilent to
simply declaring the object previously and initializing it with the
exiting object, and certainly not different to the extent of, if I
understand you correctly, not even using the heap at all.

Thank you again for pointing me in the right direction

-sb



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: GNAT - return by anonymous access
  2011-12-23 13:20                   ` Simon Belmont
@ 2011-12-27 23:51                     ` Randy Brukardt
  0 siblings, 0 replies; 19+ messages in thread
From: Randy Brukardt @ 2011-12-27 23:51 UTC (permalink / raw)


"Simon Belmont" <sbelmont700@gmail.com> wrote in message 
news:bc9926b7-e35b-43a1-adf7-82a936141dd6@m7g2000vbc.googlegroups.com...
On Dec 22, 7:56 pm, "Randy Brukardt" <ra...@rrsoftware.com> wrote:
...
>However, it's good
>to know that using a 'coextension' has such counter-intuitive
>operation.  I assumed that it would be functionally equivilent to
>simply declaring the object previously and initializing it with the
>exiting object, and certainly not different to the extent of, if I
>understand you correctly, not even using the heap at all.

A 'coextension' is supposed to have the same lifetime as the enclosing 
object. That means that if the enclosing object is declared on the stack, 
then the coextension should be allocated (at least logically) on the stack. 
Adding to this brew is the fact that limited objects are built-in-place, so 
the return statement you wrote is really creating the new object somewhere 
else (quite possibly on the stack). This requires a lot of shuffling, so it 
is not surprising that it can get buggy.

Janus/Ada allocates some dynamically sized objects on the heap (even when 
they logically are on the stack) and cleans them up when the stack is 
popped. So it isn't quite as hard for us (but it still is a struggle to get 
such things on the right list, and not one that is too inner). But for 
implementations that use a secondary stack for all such objects, this must 
be a nightmare (either leaking memory or freeing it too soon seems to be 
required).

                                   Randy.





^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2011-12-27 23:51 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-12-17 19:17 GNAT - return by anonymous access Simon Belmont
2011-12-17 19:51 ` Simon Wright
2011-12-18  9:08 ` Georg Bauhaus
2011-12-19 23:46 ` Randy Brukardt
2011-12-20  0:14   ` Shark8
2011-12-20 23:18     ` Randy Brukardt
2011-12-21  0:44       ` Simon Belmont
2011-12-21  7:29         ` AdaMagica
2011-12-21 11:05           ` Georg Bauhaus
2011-12-21 11:43             ` AdaMagica
2011-12-21 12:05               ` Georg Bauhaus
2011-12-22  0:33                 ` Randy Brukardt
2011-12-22  0:33           ` Simon Belmont
2011-12-22  7:11             ` Adam Beneschan
2011-12-22 22:11               ` Simon Belmont
2011-12-23  0:56                 ` Randy Brukardt
2011-12-23 13:20                   ` Simon Belmont
2011-12-27 23:51                     ` Randy Brukardt
2011-12-20 23:53 ` anon

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