* Non_Primitive Operations and Object.Operation Resolution
@ 2016-04-20 23:59 Jeffrey R. Carter
2016-04-21 20:28 ` Randy Brukardt
2016-04-22 23:49 ` ytomino
0 siblings, 2 replies; 9+ messages in thread
From: Jeffrey R. Carter @ 2016-04-20 23:59 UTC (permalink / raw)
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.
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.
--
Jeff Carter
"[M]any were collected near them, ... to
enjoy the sight of a dead young lady, nay,
two dead young ladies, for it proved twice
as fine as the first report."
Persuasion
155
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Non_Primitive Operations and Object.Operation Resolution
2016-04-20 23:59 Non_Primitive Operations and Object.Operation Resolution Jeffrey R. Carter
@ 2016-04-21 20:28 ` Randy Brukardt
2016-04-21 21:13 ` Jeffrey R. Carter
2016-04-22 23:49 ` ytomino
1 sibling, 1 reply; 9+ messages in thread
From: Randy Brukardt @ 2016-04-21 20:28 UTC (permalink / raw)
"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.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Non_Primitive Operations and Object.Operation Resolution
2016-04-21 20:28 ` Randy Brukardt
@ 2016-04-21 21:13 ` Jeffrey R. Carter
2016-04-22 6:27 ` AdaMagica
2016-04-22 22:24 ` Randy Brukardt
0 siblings, 2 replies; 9+ messages in thread
From: Jeffrey R. Carter @ 2016-04-21 21:13 UTC (permalink / raw)
On 04/21/2016 01:28 PM, Randy Brukardt wrote:
>
> 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).
T is Digits_Lists.Vector. I don't see any way that Unbounded_Integers.Element
could be in the declarative region of that (Digit_Lists) or of any ancestor
(such as Ada.Finalization.Controlled).
> 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.)
What I provided is the actual code, just not /all/ of the actual code. I don't
see anything in the full code that would make the pkg body be part of the
declarative region of the type or any ancestor. I can provide the full pkg, or
you can obtain it from pragmada.x10hosting.com or
https://github.com/jrcarter/PragmARC
> If you would like, I could take this to the ARG and see if anyone has any
> insight.
That would probably be a good idea. Subtypes are not types and I'd think should
not be considered an ancestor of the type. Considering a subtype as an ancestor
seems like it would be a disaster.
> 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. :-)
Perhaps. Element seemed the best name at the time, given my limited
understanding of the language.
--
Jeff Carter
"I was either in love, or I had smallpox."
Take the Money and Run
137
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Non_Primitive Operations and Object.Operation Resolution
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
1 sibling, 1 reply; 9+ messages in thread
From: AdaMagica @ 2016-04-22 6:27 UTC (permalink / raw)
Am Donnerstag, 21. April 2016 23:13:19 UTC+2 schrieb Jeffrey R. Carter:
> That would probably be a good idea. Subtypes are not types and I'd think should
> not be considered an ancestor of the type. Considering a subtype as an ancestor
> seems like it would be a disaster.
Only, subtypes have names, the type of a subtype is anonymous. What you see in a type declaration is the first subtype.
Don't know whether this is related to your problen - just to corret the nomenclature.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Non_Primitive Operations and Object.Operation Resolution
2016-04-22 6:27 ` AdaMagica
@ 2016-04-22 18:24 ` Jeffrey R. Carter
0 siblings, 0 replies; 9+ messages in thread
From: Jeffrey R. Carter @ 2016-04-22 18:24 UTC (permalink / raw)
On 04/21/2016 11:27 PM, AdaMagica wrote:
> Am Donnerstag, 21. April 2016 23:13:19 UTC+2 schrieb Jeffrey R. Carter:
>> That would probably be a good idea. Subtypes are not types and I'd think should
>> not be considered an ancestor of the type. Considering a subtype as an ancestor
>> seems like it would be a disaster.
>
> Only, subtypes have names, the type of a subtype is anonymous. What you see in a type declaration is the first subtype.
>
> Don't know whether this is related to your problen - just to corret the nomenclature.
Yes. However, the definition of "ancestor" uses the term "type", not "subtype".
--
Jeff Carter
"Go and boil your bottoms."
Monty Python & the Holy Grail
01
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Non_Primitive Operations and Object.Operation Resolution
2016-04-21 21:13 ` Jeffrey R. Carter
2016-04-22 6:27 ` AdaMagica
@ 2016-04-22 22:24 ` Randy Brukardt
2016-04-23 0:37 ` Jeffrey R. Carter
1 sibling, 1 reply; 9+ messages in thread
From: Randy Brukardt @ 2016-04-22 22:24 UTC (permalink / raw)
"Jeffrey R. Carter" <spam.jrcarter.not@spam.not.acm.org> wrote in message
news:nfbfj0$1m2$1@dont-email.me...
> On 04/21/2016 01:28 PM, Randy Brukardt wrote:
...
>> If you would like, I could take this to the ARG and see if anyone has any
>> insight.
>
> That would probably be a good idea. Subtypes are not types and I'd think
> should not be considered an ancestor of the type. Considering a subtype as
> an ancestor seems like it would be a disaster.
I've sent the question to the ARG. But I don't see any "disaster" even if
the subtype is included; there shouldn't be routines with the same name and
profile sitting around to get picked up anyway.
>> 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. :-)
>
> Perhaps. Element seemed the best name at the time, given my limited
> understanding of the language.
My view is that anytime you have more than one visible (note: not
necessarily *directly* visible) entity with the same name and same profile,
but has different semantics, you have unnecessarily tricky code, regardless
of the legality of that code. A reader of the code could very well refer to
the wrong declaration (programmers are not great at figuring out the nuances
of Ada visibility rules), and that could lead to problems during program
maintance (especially if that maintenance is done by someone other than the
original author). As such, I'd suggest that the routine in the body be named
something like Safe_Element just to reduce this potential confusion. (I know
*I* could very well use the wrong routine in debugging this package.)
Still, legal Ada code ought to compile. even when it isn't a good idea. :-)
Randy.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Non_Primitive Operations and Object.Operation Resolution
2016-04-20 23:59 Non_Primitive Operations and Object.Operation Resolution Jeffrey R. Carter
2016-04-21 20:28 ` Randy Brukardt
@ 2016-04-22 23:49 ` ytomino
2016-04-23 0:38 ` Jeffrey R. Carter
1 sibling, 1 reply; 9+ messages in thread
From: ytomino @ 2016-04-22 23:49 UTC (permalink / raw)
I think It's a bug of the compiler.
I tried to move the prototype of Element from body to spec.
Then, I got success to compile it with gcc-6.0.0-20160401.
--- pragmarc-unbounded_integers.ads.orig 2016-04-23 08:45:44.000000000 +0900
+++ pragmarc-unbounded_integers.ads 2016-04-23 08:46:12.000000000 +0900
@@ -72,6 +72,10 @@
Negative : Boolean := False;
Digit : Digit_List := Single_Zero;
end record;
+
+ 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
+
end PragmARC.Unbounded_Integers;
--
-- This is free software; you can redistribute it and/or modify it under
--- pragmarc-unbounded_integers.adb.orig 2016-04-23 08:45:48.000000000 +0900
+++ pragmarc-unbounded_integers.adb 2016-04-23 08:46:08.000000000 +0900
@@ -14,9 +14,6 @@
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
-
procedure Insert (List : in out Digit_List; Index : in Positive; Value : in Digit_Value);
-- If Index is a valid index into List, replaces the digit at Index with Value;
-- otherwise, appends zeros to List until Index - 1 is a valid index, then appends Value to List
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Non_Primitive Operations and Object.Operation Resolution
2016-04-22 22:24 ` Randy Brukardt
@ 2016-04-23 0:37 ` Jeffrey R. Carter
0 siblings, 0 replies; 9+ messages in thread
From: Jeffrey R. Carter @ 2016-04-23 0:37 UTC (permalink / raw)
On 04/22/2016 03:24 PM, Randy Brukardt wrote:
>
> My view is that anytime you have more than one visible (note: not
> necessarily *directly* visible) entity with the same name and same profile,
> but has different semantics, you have unnecessarily tricky code, regardless
> of the legality of that code. A reader of the code could very well refer to
> the wrong declaration (programmers are not great at figuring out the nuances
> of Ada visibility rules), and that could lead to problems during program
> maintance (especially if that maintenance is done by someone other than the
> original author). As such, I'd suggest that the routine in the body be named
> something like Safe_Element just to reduce this potential confusion. (I know
> *I* could very well use the wrong routine in debugging this package.)
It seems clear to me, but I guess I'm weird. Generic iterators (which I've been
using since Ada 83 was the current version) seem clear to me, but I recall
reading somewhere that some ARG members found them confusing.
> Still, legal Ada code ought to compile. even when it isn't a good idea. :-)
Absolutely.
--
Jeff Carter
"Go and boil your bottoms."
Monty Python & the Holy Grail
01
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Non_Primitive Operations and Object.Operation Resolution
2016-04-22 23:49 ` ytomino
@ 2016-04-23 0:38 ` Jeffrey R. Carter
0 siblings, 0 replies; 9+ messages in thread
From: Jeffrey R. Carter @ 2016-04-23 0:38 UTC (permalink / raw)
On 04/22/2016 04:49 PM, ytomino wrote:
> I think It's a bug of the compiler.
>
> I tried to move the prototype of Element from body to spec.
> Then, I got success to compile it with gcc-6.0.0-20160401.
That does seem indicative of a compiler error. Where the declaration appears
shouldn't make a difference.
--
Jeff Carter
"Go and boil your bottoms."
Monty Python & the Holy Grail
01
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2016-04-23 0:38 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-04-20 23:59 Non_Primitive Operations and Object.Operation Resolution Jeffrey R. Carter
2016-04-21 20:28 ` Randy Brukardt
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
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox