From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.3 required=5.0 tests=BAYES_00,INVALID_MSGID autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,feb9db77c9b5b310 X-Google-Attributes: gid103376,public From: bobduff@world.std.com (Robert A Duff) Subject: Re: Access to Unconstrained Arrays Date: 1997/04/21 Message-ID: #1/1 X-Deja-AN: 236334417 References: <335507B4.7A03@boeing.com> <3357B77F.44EE@boeing.com> <1997Apr21.005646.25460@ocsystems.com> Organization: The World Public Access UNIX, Brookline, MA Newsgroups: comp.lang.ada Date: 1997-04-21T00:00:00+00:00 List-Id: In article <1997Apr21.005646.25460@ocsystems.com>, Joel VanLaven 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