From: "Adam Beneschan" <adam@irvine.com>
Subject: Re: Universal float or not - who's right ?
Date: 8 Sep 2006 10:13:37 -0700
Date: 2006-09-08T10:13:37-07:00 [thread overview]
Message-ID: <1157735617.791199.13280@e3g2000cwe.googlegroups.com> (raw)
In-Reply-To: 45016cb7$1_4@news.bluewin.ch
Gautier wrote:
> Hullo - here is a nice case, with a trivial workaround given first, where 3
> compiler differs. Question to the Ada RM exegetes: who is right ?
>
> package FF is
> type FFloat is new Float;
> end;
> with FF;
>
> procedure Beauripple is
>
> generic
> type Num is digits <>;
> x : Num;
> package P is end;
>
> c: constant:= 2.0**4;
> package FPc is new P(FF.FFLoat,c);
> -- Passes on compilers A,B,C - as expected
>
> d: constant FF.FFLoat:= 2.0**4;
> -- Fails on compiler A,B,C
> -- "**" is not visible, an "use FF;" is missing
>
> package FPe is new P(FF.FFLoat,2.0**4);
> -- ** A,B,C differ:
> -- Passes on C: (2.0**4) probably taken as universal float
> -- Fails on compiler A,B: same reason as for constant d
>
> begin
> null;
> end;
The declaration of "d" and of the instance FPe should both be rejected,
but understanding why requires understanding the difference between
universal_real and root_real, which is something that always confuses
the daylights out of me, so I hope I'm getting this right. All
floating-point literals are universal_real and can be used as an actual
for any subprogram parameter that is of any real type. However,
universal_reals don't have primitive subprograms, so there's no "**"
that returns a universal_real. Instead, there's a "**" that takes a
root_real and an Integer'Base parameter and returns a root_real. When
you say 2.0**4, and the "**" implicitly defined for FFloat is not
visible, then "**" can refer to the subprogram
function "**" (Left : root_real; Right : Integer'Base) return
root_real;
or to a "**" function defined for a predefined type like Float.
When you say
d: constant FF.FFloat := 2.0**4;
the expected type for the expression is FF.FFloat. This means that the
expression can have type FF.FFloat or it can be a universal_real, but
it can't be any other type, including root_real. So it's illegal. The
exact same logic applies to the instantiation---the expected type for
the generic actual parameter is Num, which is the same as FF.FFloat.
(So compiler C is wrong to accept it.)
Both of these will work, though:
d: constant FF.FFloat := c;
d: constant FF.FFloat := FF.FFloat (2.0**4); --type conversion,
not qualified expression!!
The first works because "c" is a named number and therefore has type
universal_real; in the second case, 2.0**4 will have type root_real
which can be converted to FF.FFloat. Similarly for the instantiation
(you've already demonstrated that using the named number works).
References: RM95 3.3.1(4), 3.3.2(3,5), 3.4.1(6-7), 4.5.6(9-10),
8.6(22,24,29), 12.4(4)
Hope this helps.
-- Adam
next prev parent reply other threads:[~2006-09-08 17:13 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-09-08 13:14 Universal float or not - who's right ? Gautier
2006-09-08 17:13 ` Adam Beneschan [this message]
2006-09-09 1:35 ` Randy Brukardt
2006-09-11 19:44 ` Adam Beneschan
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox