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,9a4a0b8e5206a866 X-Google-Attributes: gid103376,public From: stt@houdini.camb.inmet.com (Tucker Taft) Subject: Re: Conversion of Access Types Question Date: 1999/01/14 Message-ID: #1/1 X-Deja-AN: 432713505 Sender: news@inmet.camb.inmet.com (USENET news) X-Nntp-Posting-Host: houdini.camb.inmet.com References: <369E4ACA.B8B07871@neta.com> Organization: Intermetrics, Inc. Newsgroups: comp.lang.ada Date: 1999-01-14T00:00:00+00:00 List-Id: Paul S. Heidmann (psh@neta.com) wrote: : David C. Hoos, Sr. wrote: : > : > Paul S. Heidmann wrote in message <369DFFFC.A160D47C@neta.com>... : > >Greetings fellow Ada lovers! : > > : > >I'm an experienced Ada83 programmer that is learning to use Ada95. : > >Things are going very well, but I don't understand the problems : > >that I'm having converting access types that point to variables of : > >class wide types. Consider the following piece of code: : > > : > >======================================= : > > : > >procedure Types is : > > : > > type T1 is tagged : > > record : > > I : Integer; : > > end record; : > > type A_T1 is access all T1'Class; : > > : > > type T2 is new T1 with : > > record : > > I2 : Integer; : > > end record; : > > type A_T2_Classwide is access all T2'Class; : > > type A_T2 is access T2; : > > : > > Thing1 : A_T1; : > > Thing2 : A_T2_Classwide; : > > Thing3 : A_T2; : > > : > >begin : > > Thing1 := new T2; : > > Thing2 := A_T2_Classwide (Thing1); : > > Thing3 := A_T2 (Thing1); -- illegal, types are not convertable. : > >end Types; : > > : > >======================================= : > > : > >My question is, why is the last line an illegal conversion, but the : > >second to last line not? There are number of rules relating to access type conversion: 1) If you omit the "all" or the "constant" in the access type definition, then you can only convert *to* such an access type from another access type with a common ancestor, meaning that you have declared one or more access types derived from the same access type. This circumstance comes up very rarely. Hence, the simpler rule-of-thumb is that if you want to convert *to* a particular access type, it must be declared with an "all" or "constant" modifier. You can convert *from* an access type without the "all" or "constant" modifier. The reason for this is that pool-specific access types (those without the "all"/"constant") can have an optimized representation (such as an index or offset), allowing them to only point into a single access type storage "pool." By constrast, "general" access types have a representation which allows them to point into any storage-pool, meaning that their representation is generally a full machine address. 2) Presuming the target access type has an "all" or "constant," then the designated type of the target must be the same, or be a tagged type and the target designated type must be an ancestor of the source designated type, or be "covered" by the source designated type (implying the source designated type must be class-wide). This later case requires an additional run-time check. 3) You can't convert an access-to-constant value to an access-to-variable type (none of that "casting away const'ness" allowed in Ada). : ... : I already understood that could solve the problem by making A_T2 : a generalized access type (that's why I have type A_T2_Classwide, : above). I question is why is this the case? I could have been : clearer... Let me give it another try. The rule-of-thumb given above is that you must specify "all" on the target type of an access-type conversion. I.e it must be a "general" access type. : A_T2_Classwide is an access type to a group of types rooted at : T2. In my understanding, the 'class, when applied to T2, refers : to a set of types rooted at T2. T1, in the above code, would not be : in T2'class, right? T2 would be in T1'class, however. Therefore, : A_T1 could point to an object of type T1 or of type T2 (and can, see : first line of code). If Thing1, above, points to an object of type : T2 (and it does), then I should be able to covert it to A_T2 (but I : can't). Why is it that adding a 'class, which only refers to things : derived from T2, makes the conversion from A_T1 (which has nothing to : do with T2'Class) legal? I think you are still getting confused. Conversion requires the target access type to be a general access type. This is the first requirement. Then there are additional requirements about the designated types, as summarized above. : Thanks! : Paul Heidmann -- -Tucker Taft stt@averstar.com http://www.averstar.com/~stt/ Technical Director, Distributed IT Solutions (www.averstar.com/tools) AverStar (formerly Intermetrics, Inc.) Burlington, MA USA