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,4651b0d82680c5d2 X-Google-Attributes: gid103376,public From: jsa@alexandria (Jon S Anthony) Subject: Re: Polymorphism/Inheritence Date: 1997/02/26 Message-ID: #1/1 X-Deja-AN: 221897456 Distribution: world References: <5f0pcc$5b9@news.cps.udayton.edu> Organization: PSI Public Usenet Link Newsgroups: comp.lang.ada Date: 1997-02-26T00:00:00+00:00 List-Id: In article <5f0pcc$5b9@news.cps.udayton.edu> abacon@cps.udayton.edu (Adam C. Bacon) writes: > type Vehicle is tagged private; > > I also have a pointer declared as follows: > type Vehicle_Pointer is access Vehicle'Class; > > In a child package specification, I have a private type declared as follows: > type Car is new Vehicle with private; > > I have two local variables defined in the child package body as follows: > Pointer : Vehicle_Pointer; > Temp_Car : Car; > > The problem that I have arises when I make an assignment in a function > defined in the child package body. The assignment occurs in a Create > procedure, which is as follows: > Pointer.all := Temp_Car; > > Prior to this assignment, I make the following: > Pointer := new Car; > > The error which I receive from the compiler is the following: > Pointer.all := Temp_Car; > | > dynamically tagged expression required This has something to do with the fact that class wide objects (like your pointer.all) are dynamically tagged while temp_car is statically tagged. But that's not all there is to it. For one thing, a statically tagged object used as an actual to a class wide parameter in a call is first implicitly converted to the class wide type. The same thing as happens in: X : Vehicle'Class := Temp_Car; So, the error message here seems irrelevant. But that's not all. This seems to be one of those areas in the RM where the more you dig the less you end up knowing. We do know that a class wide type (like the designation of Vehicle_Pointer) is indefinite (here, this means has unknown discriminants). We also know that this means that any object of the type will thus have an actual subtype which is constrained (by the initial value) and so the object is constrained. Now, once you have a constrained object you can't change it - or at least that's what I've long thought and there are several hints in the RM that this is true (like the notes in 3.7), but I cannot find the rule which either says this or implies it. So, this might not actually be true. If it is true, then your assignment is really wrong since it is trying to change a constrained object (this despite the fact that the discriminant of the actual constrained subtype is the same as that of Car). OTOH, 4.6(21,22,52) seems to indicate that maybe you can do this conversion after all, but you have to give an explicit subtype_mark. For example, if you change to: Pointer.all := Vehicle'Class(Temp_Car); Now, this compiles and runs OK on GNAT 3.09. But I don't know if it is really correct... /Jon -- Jon Anthony Organon Motives, Inc. Belmont, MA 02178 617.484.3383 jsa@organon.com