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: "David C. Hoos, Sr." Subject: Re: Conversion of Access Types Question Date: 1999/01/14 Message-ID: <77llgq$i3v@hobbes.crc.com>#1/1 X-Deja-AN: 432684765 References: <369DFFFC.A160D47C@neta.com> <77l492$b5s@hobbes.crc.com> <369E4ACA.B8B07871@neta.com> X-MimeOLE: Produced By Microsoft MimeOLE V4.72.3110.3 Organization: Coleman Research Corporation Newsgroups: comp.lang.ada Date: 1999-01-14T00:00:00+00:00 List-Id: Paul S. Heidmann wrote in message <369E4ACA.B8B07871@neta.com>... >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? >> > >> Compiling your code with gnat results in the following message: >> >> [hoosd@VISNT021 d:/gnat_examples]$ gcc -c types.adb >> types.adb:23:14: target type must be general access type >> types.adb:23:14: add "all" to type "A_T2" defined at line 14 >> >> Making the change the compiler directs solves the problem. >> >> i.e., change line 14 to read: >> type A_T2 is access all T2; > >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. > >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? > It's not the 'class which made the conversion from A_T1 to A_T2_Classwide legal, it's the "all" in the declaration of A_T2_Classwide which makes it legal. Without the "all" (i.e. the target type is not a general access type), then the rule of LRM 4.6(21) comes into play: Specifically, there is no type which is an ancestor of both the target type (A_T1), and of the operand type (A_T2). Making the target type a general access type brings into play the less-restrictive rules of 4.6(13-17). Hope this helps. David C. Hoos, Sr.