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