comp.lang.ada
 help / color / mirror / Atom feed
From: "Randy Brukardt" <randy@rrsoftware.com>
Subject: Re: Non_Primitive Operations and Object.Operation Resolution
Date: Thu, 21 Apr 2016 15:28:13 -0500
Date: 2016-04-21T15:28:13-05:00	[thread overview]
Message-ID: <nfbd4t$4n4$1@loke.gir.dk> (raw)
In-Reply-To: nf94tt$9iv$1@dont-email.me

"Jeffrey R. Carter" <spam.jrcarter.not@spam.not.acm.org> 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. 



  reply	other threads:[~2016-04-21 20:28 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-04-20 23:59 Non_Primitive Operations and Object.Operation Resolution Jeffrey R. Carter
2016-04-21 20:28 ` Randy Brukardt [this message]
2016-04-21 21:13   ` Jeffrey R. Carter
2016-04-22  6:27     ` AdaMagica
2016-04-22 18:24       ` Jeffrey R. Carter
2016-04-22 22:24     ` Randy Brukardt
2016-04-23  0:37       ` Jeffrey R. Carter
2016-04-22 23:49 ` ytomino
2016-04-23  0:38   ` Jeffrey R. Carter
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox