Version 1.1 of acs/ac-00087.txt

Unformatted version of acs/ac-00087.txt version 1.1
Other versions for file acs/ac-00087.txt

!standard 04.05.02(03)          03-12-05 AC95-00087/01
!standard 03.05(04)
!standard 03.05(05)
!standard 04.04(03)
!class amendment 03-12-05
!status received no action 03-12-05
!status received 03-11-03
!subject Universal integer ranges
!appendix

!topic Universal integer ranges in membership tests
!reference 4.5.2(3), 3.5(4-5), 4.4(3)
!from Adam Beneschan 11-03-03
!discussion

In this construct:

    B : Boolean := <some-expression> in 5 .. 10;

4.5.2(3) says that the "tested type" of a membership test is the type
of the range, and that the expected type for <some-expression> is the
tested type.  But what is the tested type?

There doesn't seem to be anywhere that defines the type of the range.
3.5(4) says that a _range_ specifies a subset of the values of "some"
scalar type.  Other sections define what the expected type of the
range is in specific contexts.  In "subtype Subtype_1 is Subtype_2
range M .. N", 3.5(5) says "the type of the range shall resolve to
that of the type determined by the subtype_mark".  If a
discrete_subtype_indication is a range, 3.6(8) and 3.6(18) describe
how the range type is to be determined, which in the case of two
universal integers will be the type Standard.Integer.  4.1.2(4) says
that when a range is used in a slice, the expected type of the range
is the index type of the array type.

But there doesn't seem to be any similar language saying what the
expected type of a range is in the case of a membership test.

This seems to make a difference because I can't figure out whether the
following should produce an error at compile time:

    package Pak1 is
        type T1 is mod 2;
    end Pak1;

    with Pak1;
    procedure Proc1 (X : Pak1.T1) is
    begin
        if X in 5 .. 10 then . . . . . . .

If the type of the range is Pak1.T1, then an error should be produced
at compile time because of 4.9(35) (since 5 and 10 are static
expressions that are not in the base range of their expected type).
But if the type of the range is universal_integer, then the construct
seems to be legal.  I don't see anything in RM95 that would make
either interpretation incorrect.

****************************************************************

From: Tucker Taft
Sent: Tuesday, November 4, 2003  7:29 AM

> There doesn't seem to be anywhere that defines the type of the range.

3.5(5) is the relevant paragraph, which says:
    ... For a range of a given type, the simple expressions
    of the range are expected to be of the type of the range.

This coupled with 4.5.2(3) gives overload resolution all the
information it needs to know what are the "acceptable
interpretations" of the membership test construct.
This is not particularly different from an equality
test between a variable and a literal, except that
with the equality test, there is an additional requirement
that the "=" operator be directly visible.  There is
no visibility requirement for membership test operations.

However, I think you have found a legitimate "hole" in that
nowhere do we make it clear that the type of a range is
always a *specific* type.  For the purposes of overload resolution,
we treat the ".." operation very much like a primitive operator
(see 8.6(29)), and universal types don't have primitive operators
(as specified in 3.4.1(7)), but we do not seem to say directly
that universal types do not have ranges (i.e. ".." is not
defined for universal types).

> ...
> But there doesn't seem to be any similar language saying what the
> expected type of a range is in the case of a membership test.

It is stated the other way, namely that the type of the range
determines the expected type for the expression.

It doesn't make much difference, since overload resolution
is generally a symmetric process, which some implementors call
"balancing," where one has to find the types that satisfy
all the overload and name resolution rules.  If there are
multiple acceptable interpretations, then some sort of
preference rule may be required.

However, as mentioned above, the RM does not seem to make
it clear that ".." is not defined for universal types,
so you would be correct in saying there would be ambiguity
in your example.  In fact, if ".." were permitted for universal
types, then *every* membership test involving numeric types
would be ambiguous.  So applying Robert Dewar's "the RM never
says anything silly" rule, we must conclude that ".." is not
defined for universal types.  But in any case, one doesn't
like to fall back on the no-sillyness rule, so I agree we
should probably add to 3.5(4) that the type of a range
is a specific type (or perhaps put this in 3.4.1(7)?).

>
> This seems to make a difference because I can't figure out whether the
> following should produce an error at compile time:
>
>     package Pak1 is
>         type T1 is mod 2;
>     end Pak1;
>
>     with Pak1;
>     procedure Proc1 (X : Pak1.T1) is
>     begin
>         if X in 5 .. 10 then . . . . . . .
>
> If the type of the range is Pak1.T1, then an error should be produced
> at compile time because of 4.9(35) (since 5 and 10 are static
> expressions that are not in the base range of their expected type).
> But if the type of the range is universal_integer, then the construct
> seems to be legal.  I don't see anything in RM95 that would make
> either interpretation incorrect.

Except for the no-sillyness rule, I agree you are correct.  But
if universal types were permitted for ranges, then all scalar
membership tests would be ambiguous, so clearly we have to rule
that out somehow.  An appropriate addition of the word "specific"
somewhere in 3.5(4) is probably the right answer.

****************************************************************

From: Adam Beneschan
Sent: Tuesday, November 4, 2003 11:11 AM

What makes it seem different to me is that in the case

   if X = 3 then ...

you can determine the meaning of "=" by gathering all the visible "="
functions and determining which ones fit the parameters by using the
rules that "the expected type for an actual parameter is the type of
the corresponding formal parameter" (6.4.1(3)), "if the expected type
for a construct is a specific type T, the type of the construct [may
resolve to] a universal type that covers T" (8.6(22,24)), and "an
integer literal is of type universal_integer" (4.2(8)).  [Plus a
couple others such as 5.3(4).]  No "symmetry" concept is needed to
work all this out.  When I tried to use a similar approach to
determine the meaning of the membership test, I gave myself a
headache.

****************************************************************


Questions? Ask the ACAA Technical Agent