* Access to Unconstrained Arrays @ 1997-04-16 0:00 John Harbaugh 1997-04-18 0:00 ` Robert Dewar ` (2 more replies) 0 siblings, 3 replies; 9+ messages in thread From: John Harbaugh @ 1997-04-16 0:00 UTC (permalink / raw) When trying to pass pointers to objects of unconstrained array type, I am getting confusing compiler errors. For example: procedure Main is type Lists is array(Natural range <>) of Integer; type Lists_Ptrs is access all Lists; procedure Do_Something(To : in out Lists_Ptrs) is... List1 : Lists(1..4) := (1,2,3,4); List2 : Lists := (1,2,3,4); begin Do_Something(To => List1); -- Compilation Error. Why? Do_Something(To => List2); -- No problemo!!! end Main; List1 should be an anonymous constrained subtype of type Lists. I was under the impression that subtypes are simply a subset of their base type. Is this not the case for constrained subtypes of unconstrained types? Thanks in advance for any who may respond. - John ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Access to Unconstrained Arrays 1997-04-16 0:00 Access to Unconstrained Arrays John Harbaugh @ 1997-04-18 0:00 ` Robert Dewar 1997-04-18 0:00 ` Joel VanLaven 1997-04-18 0:00 ` John Harbaugh 2 siblings, 0 replies; 9+ messages in thread From: Robert Dewar @ 1997-04-18 0:00 UTC (permalink / raw) John says <<procedure Main is type Lists is array(Natural range <>) of Integer; type Lists_Ptrs is access all Lists; procedure Do_Something(To : in out Lists_Ptrs) is... List1 : Lists(1..4) := (1,2,3,4); List2 : Lists := (1,2,3,4); begin Do_Something(To => List1); -- Compilation Error. Why? Do_Something(To => List2); -- No problemo!!! end Main; List1 should be an anonymous constrained subtype of type Lists. I was under the impression that subtypes are simply a subset of their base type. Is this not the case for constrained subtypes of unconstrained types? Thanks in advance for any who may respond..>> The compiler messages are correct. Your pointer type can only point to objects of the appropriate unconstrained type, like List2. But the type of List1 is constrained (pretty clearly from your source!!!) so it is not suitable. This somewhat annoying rule was done to save a little bit of memory in some implementations (in some implementations, List2 will materialize a dope, and List1 will not. Incidentally, it is helpful if you are careful to post the EXACT sources that you used, the source above is obvious junk (since you pass the wrong type in both calls), but I am assumning some obvoius repair (such as add aliased to both declarations, and replace in out with access. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Access to Unconstrained Arrays 1997-04-16 0:00 Access to Unconstrained Arrays John Harbaugh 1997-04-18 0:00 ` Robert Dewar @ 1997-04-18 0:00 ` Joel VanLaven 1997-04-20 0:00 ` Robert Dewar 1997-04-18 0:00 ` John Harbaugh 2 siblings, 1 reply; 9+ messages in thread From: Joel VanLaven @ 1997-04-18 0:00 UTC (permalink / raw) John Harbaugh (john.s.harbaugh2@boeing.com) wrote: : When trying to pass pointers to objects of unconstrained array type, I : am getting confusing compiler errors. For example: : procedure Main is : type Lists is array(Natural range <>) of Integer; : type Lists_Ptrs is access all Lists; : procedure Do_Something(To : in out Lists_Ptrs) is... : List1 : Lists(1..4) := (1,2,3,4); : List2 : Lists := (1,2,3,4); : begin : Do_Something(To => List1); -- Compilation Error. Why? : Do_Something(To => List2); -- No problemo!!! : end Main; : List1 should be an anonymous constrained subtype of type Lists. I was : under the impression that subtypes are simply a subset of their base : type. Is this not the case for constrained subtypes of unconstrained : types? I think your compiler is stopping at the first error or something. Our compiler says that both calls are incorrect. List1 and List2 are arrays, NOT access values. So, neither call matches the procedure profile. In fact, List2 IS constrained. It is given a constraint when it is initialized. If your program were to assign (1,2) to either list it would raise a constraint error (the same as for list1). Did you try commenting out the first call? I hope that the compiler you are using does not really accept the second call. If it does either it is a bug in your compiler or in ours :). I am betting that neither has a bug with respect to this. To make this compile, you need to either change Do_Something or change the two object declarations to be something like List1 : Lists_Ptrs := new lists'(1,2,3,4); List2 : Lists_Ptrs := new lists'(1,2,3,4); : Thanks in advance for any who may respond. : - John No problem, -- -- Joel VanLaven ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Access to Unconstrained Arrays 1997-04-18 0:00 ` Joel VanLaven @ 1997-04-20 0:00 ` Robert Dewar 0 siblings, 0 replies; 9+ messages in thread From: Robert Dewar @ 1997-04-20 0:00 UTC (permalink / raw) Joel said <<I think your compiler is stopping at the first error or something. Our compiler says that both calls are incorrect. List1 and List2 are arrays, NOT access values. So, neither call matches the procedure profile. In fact, List2 IS constrained. It is given a constraint when it is initialized. If your program were to assign (1,2) to either list it would raise a constraint error (the same as for list1).>> Of course the program is incorrect as presented, but one has to assume that was just a typo introduced in preparation. if you make the obvious changes, there is *indeed* a subtle difference between the two cases, see my previous post. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Access to Unconstrained Arrays 1997-04-16 0:00 Access to Unconstrained Arrays John Harbaugh 1997-04-18 0:00 ` Robert Dewar 1997-04-18 0:00 ` Joel VanLaven @ 1997-04-18 0:00 ` John Harbaugh 1997-04-20 0:00 ` Robert Dewar 1997-04-21 0:00 ` Joel VanLaven 2 siblings, 2 replies; 9+ messages in thread From: John Harbaugh @ 1997-04-18 0:00 UTC (permalink / raw) John Harbaugh wrote: > > When trying to pass pointers to objects of unconstrained array type, I > am getting confusing compiler errors. For example: > > procedure Main is > type Lists is array(Natural range <>) of Integer; > type Lists_Ptrs is access all Lists; > > procedure Do_Something(To : in out Lists_Ptrs) is... > > List1 : Lists(1..4) := (1,2,3,4); > List2 : Lists := (1,2,3,4); > > begin > Do_Something(To => List1); -- Compilation Error. Why? > Do_Something(To => List2); -- No problemo!!! > end Main; > > List1 should be an anonymous constrained subtype of type Lists. I was > under the impression that subtypes are simply a subset of their base > type. Is this not the case for constrained subtypes of unconstrained > types? > > Thanks in advance for any who may respond. > > - John How embarrasing, please excuse the mangled code. What I meant to show was: procedure Main is type Lists is array(Natural range <>) of Integer; type Lists_Ptrs is access all Lists; procedure Do_Something(To : in Lists_Ptrs) is separate; List1 : aliased Lists(1..4) := (1,2,3,4); List2 : aliased Lists := (1,2,3,4); Ptr : Lists_Ptrs; begin Ptr := List1'access; Do_Something(To => Ptr); -- Compilation Error. Why? Ptr := List2'access; Do_Something(To => Ptr); -- No problemo!!! end Main; Apparently, the problem is that Lists(1..4) is a different subtype indication than Lists. Sheepishly, - John ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Access to Unconstrained Arrays 1997-04-18 0:00 ` John Harbaugh @ 1997-04-20 0:00 ` Robert Dewar 1997-04-21 0:00 ` Joel VanLaven 1 sibling, 0 replies; 9+ messages in thread From: Robert Dewar @ 1997-04-20 0:00 UTC (permalink / raw) <<Apparently, the problem is that Lists(1..4) is a different subtype indication than Lists. Sheepishly,>> Exactly, one has an unconstrained nominal subtype, the other has a constrained nominal subtype (incidentally, it was absolutely clear what you intended, even though your code was indeed a bit mangled :-) ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Access to Unconstrained Arrays 1997-04-18 0:00 ` John Harbaugh 1997-04-20 0:00 ` Robert Dewar @ 1997-04-21 0:00 ` Joel VanLaven 1997-04-21 0:00 ` Robert A Duff 1 sibling, 1 reply; 9+ messages in thread From: Joel VanLaven @ 1997-04-21 0:00 UTC (permalink / raw) John Harbaugh (john.s.harbaugh2@boeing.com) wrote: : John Harbaugh wrote: : > : > When trying to pass pointers to objects of unconstrained array type, I : > am getting confusing compiler errors. For example: : > [snipped old code] : > List1 should be an anonymous constrained subtype of type Lists. I was : > under the impression that subtypes are simply a subset of their base : > type. Is this not the case for constrained subtypes of unconstrained : > types? : > : > Thanks in advance for any who may respond. : > : > - John : How embarrasing, please excuse the mangled code. What I meant to show : was: : procedure Main is : type Lists is array(Natural range <>) of Integer; : type Lists_Ptrs is access all Lists; : : procedure Do_Something(To : in Lists_Ptrs) is separate; : : List1 : aliased Lists(1..4) := (1,2,3,4); : List2 : aliased Lists := (1,2,3,4); : Ptr : Lists_Ptrs; : : begin : Ptr := List1'access; : Do_Something(To => Ptr); -- Compilation Error. Why? : Ptr := List2'access; : Do_Something(To => Ptr); -- No problemo!!! : end Main; : Apparently, the problem is that Lists(1..4) is a different subtype : indication than Lists. I agree with you that this code ought to compile. In fact, our compiler does compile your code without error or warning. Attempting to resolve the conflict between this fact and Robert Dewar's comments, I did a bit of Reference Manual snooping and found the following: RM95: 3.10(14) "The first subtype of a type defined by an access_type_definition or an access_to_object_definition is unconstrained if the designated subtype is an unconstrained array or discriminated type; otherwise it is constrained." So, the first subtype of Lists_Ptrs is an unconstrained access subtype. RM95 3.10(15) "An access value satisfies a composite_constraint of an access subtype if it equals the null value of its type or if it designates an object whose value satisfies the constraint." So, don't both list1'access and list2'access satisfy the (non-existant) composite_constraint of the first subtype of lists_ptr? Making both assignments valid, right? If someone says not, could you explain why not? (hopefully chapter and verse of the rm :) -- -- Joel VanLaven ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Access to Unconstrained Arrays 1997-04-21 0:00 ` Joel VanLaven @ 1997-04-21 0:00 ` Robert A Duff 1997-04-23 0:00 ` Robert Dewar 0 siblings, 1 reply; 9+ messages in thread From: Robert A Duff @ 1997-04-21 0:00 UTC (permalink / raw) In article <1997Apr21.005646.25460@ocsystems.com>, Joel VanLaven <jvl@ocsystems.com> wrote: >John Harbaugh (john.s.harbaugh2@boeing.com) wrote: >: procedure Main is >: type Lists is array(Natural range <>) of Integer; >: type Lists_Ptrs is access all Lists; >: >: procedure Do_Something(To : in Lists_Ptrs) is separate; >: >: List1 : aliased Lists(1..4) := (1,2,3,4); >: List2 : aliased Lists := (1,2,3,4); > >: Ptr : Lists_Ptrs; >: >: begin >: Ptr := List1'access; This 'Access is illegal by RM-3.10.2(27). Lists(1..4) does not statically match Lists; neither is Lists "discriminated and unconstrained". >: Do_Something(To => Ptr); -- Compilation Error. Why? >: Ptr := List2'access; This 'Access is legal. >: Do_Something(To => Ptr); -- No problemo!!! >: end Main; > >: Apparently, the problem is that Lists(1..4) is a different subtype >: indication than Lists. > > I agree with you that this code ought to compile. In fact, our >compiler does compile your code without error or warning. Attempting >to resolve the conflict between this fact and Robert Dewar's comments, >I did a bit of Reference Manual snooping and found the following: > >RM95: 3.10(14) > "The first subtype of a type defined by an access_type_definition or an >access_to_object_definition is unconstrained if the designated subtype is >an unconstrained array or discriminated type; otherwise it is constrained." > > So, the first subtype of Lists_Ptrs is an unconstrained access subtype. > >RM95 3.10(15) > "An access value satisfies a composite_constraint of an access subtype >if it equals the null value of its type or if it designates an object >whose value satisfies the constraint." > > So, don't both list1'access and list2'access satisfy the (non-existant) >composite_constraint of the first subtype of lists_ptr? Making both >assignments valid, right? Yes, the constraint is satisfied, but 3.10.2(27) adds a special case for arrays. There's a corresponding rule for type conversions in 4.6(16). The goal is to prevent an access-to-unconstrained-array from pointing to an object whose nominal subtype is constrained. If this were allowed, all aliased constrained arrays would have to have dope stored with them, and some Ada 83 compiler writer(s) argued that this would be hard to do. The rationale is explained in AARM-4.6(16.a). Consider that in Ada 83, if I write: type T is access String(1..8); the compiler can store 8 bytes for each allocated object, and real compilers did that. If we didn't have this special rule, compiler would have to store dope, which would increase the size to 16 bytes (on a typical 32-bit machine -- 24 bytes on a 64-bit machine, if Integer is 64 bits). Without the special rule, you could convert a value of type T to an "access all String" type, which needs dope, so the dope has to be there just in case. Similarly, for "X.all'Access", which is similar to a type conversion. Whether this size increase is important is a matter of opinion, but without the rule, clearly Ada 83 compilers would have had to change their run-time model, and we were trying to avoid that. This is an odd rule, since it treats discriminants differently from array indices, whereas discrims and indices are essentially the same thing, conceptually. (Not quite, but I think Ada would be a simpler language if they really were the same. From the point of view of the run-time model, I mean -- I understand of course that the syntax is different.) In Ada 83, if I write "type R(Discrim: ...) is record ... end; type T is access R(Discrim => 8);", the compiler can avoid storing the discriminant in each heap object. But I don't know of any Ada 83 compilers that did that, and it no longer works in Ada 95. Note that the language designers never considered using fat pointers for access-to-array. I continue to think that thin pointers are the better (simpler) solution overall. So all of this reasoning assumes thin pointers. Aside: with fat pointers, we could have allowed 'Access of slices under some circumstances. - Bob ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Access to Unconstrained Arrays 1997-04-21 0:00 ` Robert A Duff @ 1997-04-23 0:00 ` Robert Dewar 0 siblings, 0 replies; 9+ messages in thread From: Robert Dewar @ 1997-04-23 0:00 UTC (permalink / raw) Bob Duff said <<Note that the language designers never considered using fat pointers for access-to-array. I continue to think that thin pointers are the better (simpler) solution overall. So all of this reasoning assumes thin pointers. Aside: with fat pointers, we could have allowed 'Access of slices under some circumstances.>> Well of course it is true that thin pointers are simpler, but they are also less efficient. In particular, they rule out the use of virtual origins for arrays. GNAT offers the programmer the choice of fat or thin pointers (to get thin pointers, you use a size clause on the access type that restricts it to address size). However, since we do provide fat pointers, we can indeed allow 'Access of slices under some circumstances. For example, the following program with Text_IO; use Text_IO; procedure a is type ax is access all String; q : String (1 .. 11) := "Hello World"; p : ax; begin p := q (1 .. 5)'Unrestricted_Access; Put_Line (p.all); end a; Of course this program is not portable (it is relying on the implementation dependent attribute Unrestricted_Access). It is however reliably portable to all GNAT implementations. You cannot use 'Access itself this way of course, since that is not legal Ada! ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~1997-04-23 0:00 UTC | newest] Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 1997-04-16 0:00 Access to Unconstrained Arrays John Harbaugh 1997-04-18 0:00 ` Robert Dewar 1997-04-18 0:00 ` Joel VanLaven 1997-04-20 0:00 ` Robert Dewar 1997-04-18 0:00 ` John Harbaugh 1997-04-20 0:00 ` Robert Dewar 1997-04-21 0:00 ` Joel VanLaven 1997-04-21 0:00 ` Robert A Duff 1997-04-23 0:00 ` Robert Dewar
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox