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=unavailable autolearn_force=no version=3.4.4 Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!news.eternal-september.org!mx02.eternal-september.org!feeder.eternal-september.org!gandalf.srv.welterde.de!news.jacob-sparre.dk!loke.jacob-sparre.dk!pnx.dk!.POSTED!not-for-mail From: "Randy Brukardt" Newsgroups: comp.lang.ada Subject: Re: Non_Primitive Operations and Object.Operation Resolution Date: Thu, 21 Apr 2016 15:28:13 -0500 Organization: JSA Research & Innovation Message-ID: References: NNTP-Posting-Host: rrsoftware.com X-Trace: loke.gir.dk 1461270493 4836 24.196.82.226 (21 Apr 2016 20:28:13 GMT) X-Complaints-To: news@jacob-sparre.dk NNTP-Posting-Date: Thu, 21 Apr 2016 20:28:13 +0000 (UTC) X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 6.00.2900.5931 X-RFC2646: Format=Flowed; Response X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.6157 Xref: news.eternal-september.org comp.lang.ada:30228 Date: 2016-04-21T15:28:13-05:00 List-Id: "Jeffrey R. Carter" wrote in message news:nf94tt$9iv$1@dont-email.me... > Some pertinent code from PragmARC.Unbounded_Integers: > > package PragmARC.Unbounded_Integers is > ... > private -- PragmARC.Unbounded_Integers > type Calculation_Value is mod System.Max_Binary_Modulus; > > Digit_Size : constant := Calculation_Value'Size / 2; > > type Digit_Value is mod 2 ** Digit_Size; > > package Digit_Lists is new Ada.Containers.Vectors (Index_Type => > Positive, Element_Type => Digit_Value); > > subtype Digit_List is Digit_Lists.Vector; > ... > end PragmARC.Unbounded_Integers; > > package body PragmARC.Unbounded_Integers is > ... > use type Digit_List; > > function Element (List : Digit_List; Index : Positive) return > Digit_Value; > -- If Index is a valid index into List, returns the value stored there; > otherwise, returns 0 > ... > ... List.Element (Index) ... -- Index is known to be a valid index for > List > ... > ... Element (Left.Digit, I) ... I may not be a valid index for > Left.Digit > > Until recently, this was no problem. Calls like the 1st example called the > primitive Element declared in Digit_Lists. Calls like the 2nd called the > non-primitive Element declared in Unbounded_Integers, the only one > directly visible. > > Recently I've received a couple of reports that this code fails to compile > with GNAT GPL 2015. It complains, for calls like List.Element, that it > can't resolve Element, pointing to the primitive one in Digit_Lists and > the non-primitive one in Unbounded_Integers. I dismissed this as a > compiler error, since Object.Operation notation may only be used for > primitive operations. Humm. I would have agreed with you without looking it up, but that's not what the wording of 4.1.3 says. It says that "The selector_name shall resolve to denote a view of a subprogram declared immediately within the declarative region in which an ancestor of the type T is declared." It then goes on to make requirements on the first formal parameter of the subprogram (to be T, AT'Class, access T, or access AT'Class, where AT is some ancestor of T, [recall that "ancestor of T" includes T itself). Your second function Element certainly qualifies on the secondary rules. I would think that it does *not* qualify on the "declarative region" part of the rule, but since this isn't your actual code [which is likely to be subtly different], I can't say that for sure. If the declarative region of some ancestor type of Digit_Lists includes your second function Element, then the call should be ambiguous. (The declarative region includes any bodies, so putting the subprogram in the body doesn't change anything.) If Digit_List has been a derived type, then this Element routine would surely qualify (and the call would be ambiguous - although I'm not sure that the subprogram would even be legal, as it would be a non-overriding homograph of an inherited routine -- that's a rabbit hole I'm not going down now as it's not really related to your question). Assuming that there isn't anything sneaky in the part of the code that you didn't provide, it appears to me that GNAT is treating the subtype as one of the ancestors which determines the declarative region. I don't think that was the intent of the rule, but I can't say for sure. (Is a subtype of T an "ancestor of T"? Dunno). The original idea was primitives and class-wides, and subtypes don't really fit into that, but the actual wording is what matters most. I just checked the ACATS tests, and I don't see any that would insist on the subtype being considered. (But I only checked tests for 4.1.3; sometimes some unrelated test touches some corner case.) If you would like, I could take this to the ARG and see if anyone has any insight. > However, I've more recently been informed that "gcc 6" on FreeBSD gives > the same error. While I still think this is a compiler error, I thought > I'd ask the language lawyers and ARG members on here to make sure. > > Note that Unbounded_Integers is written to ISO/IEC 8652:2007, and so may > not compile with an Ada-12 compiler. For GNAT, that means it should be > compiled with the -gnat05 option. However, I see no reason why it should > not also be valid Ada 12, and it was reported that ggc 6 gives the same > error with or without that option. The wording in question was originally in ISO/IEC 8652:2007; it was changed in Ada 2012 but the change is pedantic (having to do with ignoring implicitly declared overridden primitives) and doesn't seem to have anything to do with this question. In any case, your code is unnecessarily fragile, as even if GNAT is wrong in this particular instance, future program maintenance could make the GNAT behavior correct. I'd suggest giving the non-primitive Element a different name -- less convinient, perhaps, but if you do that you don't have visit grey areas in the RM. :-) Randy.