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.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,3ed8984f81760f2e X-Google-Attributes: gid103376,public From: stt@houdini.camb.inmet.com (Tucker Taft) Subject: Re: Visibility Rules For Children Date: 1998/11/02 Message-ID: X-Deja-AN: 407451318 Sender: news@inmet.camb.inmet.com (USENET news) X-Nntp-Posting-Host: houdini.camb.inmet.com References: Organization: Intermetrics, Inc. Newsgroups: comp.lang.ada Date: 1998-11-02T00:00:00+00:00 List-Id: Matthew Heaney (matthew_heaney@acm.org) wrote: : What are the visibility rules for children? They are intended to be very similar to nested units. In general, when you declare a public child, it has the same visibility as a unit nested in the visible part of the parent's spec, whereas if you declare a private child, it has the same visibility as a unit nested in the private part of the parent's spec. In either case, the body of the child logically occurs inside the parent, "between" the private part of its spec and the beginning of its body. : In the code fragment below, I have a procedure, GC, that is a child of : parent package GP. The child is a generic that imports generic formal : type NT, derived from type T, declared in the parent package GP. : The parent type T (and its derived type NT, of course) has an Integer : component I. All the child operation does is set the value of that : component. : Yet, the compiler is telling me that the child can't see the component I : of NT: : (start of message) : q.ads:8:04: instantiation error at gp-gc.adb:3 : q.ads:8:04: undefined selector for type "NT" defined at line 6 : gnatmake: "/home/matt/acl/impls/q.ads" compilation error : Compilation exited abnormally with code 2 at Mon Oct 26 03:53:30 : (end of message) : This is unexpected, since I thought that children could see the : private components of types declared in the parent. : Does this have anything to do with the fact that the child is looking at : a type derived from the parent type, and not at the parent type : directly? Yes, and with the fact that the type NT is defined in a place where the full type of T is not visible (since the visible part of the spec of a public child does not "see" the private declarations of its parent). RM95 paragraph 7.3.1(4) is perhaps relevant here, though it is a bit unclear whether it applies to (formal) private extensions. 7.3.1(4) indicates that components of the parent become components of the derived type at the first point in the immediate scope of the derived type where the parent's components are visible. This would presumably be in the body of the child generic subprogram, since there is no private part of a (generic) subprogram. However, 7.3.1(4) explicitly talks about types defined by a derived_type_definition, which (formal) private extensions are not. Furthermore, inherited subprograms work differently for private extensions, so one might think that components should also work differently. However 7.3(16) and 12.5.1(20) say that (formal) private extensions inherit components from the ancestor type "as for a derived type defined by a derived_type_definition." All in all, there seems a bit of a muddle about component visibility of (formal) private extensions after their ancestor types become "more" visible. Probably an "AI" (Ada Interpretation) would help here... : Is a view conversion to the parent type always required here? It will certainly help! Based on the above long discourse, it is a bit unclear whether it is required. The whole issue of when private characteristics of a parent type become visible for a derived type is tricky, but a conversion to the parent type is always sure to work. : This... : procedure GP.GC (O : in out NT) is : begin : T (O).I := 1; : end; : ...instead of : procedure GP.GC (O : in out NT) is : begin : O.I := 1; : end; : Thanks, : Matt For what it is worth, after fixing the bug in "my favorite front end" which was causing it to die on this test case, it accepted your original program without complaint (i.e. it decided the parent's component "I" was visible in the body of GC). However, in a similar program where the generic subprogram was physically nested in the parent generic, it concluded that this component was not visible in the generic subprogram's body. The main difference being that the child's formal private extension is declared *after* the full type of the parent has been declared, though in a place where the full type is not yet visible, whereas in the nested case, it is declared *before* the full type has been declared. I'm not convinced this distinction is justified by the (admittedly less-than-crystal-clear) RM wording... -Tucker Taft stt@inmet.com Intermetrics, Inc. ---------------------- : generic : type FT is private; : package GP is : type T is tagged limited private; : private : type T is : tagged limited record : I : Integer; : end record; : end GP; : generic : type NT is new T with private; : procedure GP.GC (O : in out NT); : procedure GP.GC (O : in out NT) is : begin : O.I := 1; : end; : with GP; : package P is new GP (Integer); : with P; : with GP.GC; : package Q is : type NT is new P.T with null record; : procedure C is new P.GC (NT); : end; : with Q; : procedure Test_Q is : begin : null; : end; -- -Tucker Taft stt@inmet.com http://www.inmet.com/~stt/ Intermetrics, Inc. Burlington, MA USA An AverStar Company