comp.lang.ada
 help / color / mirror / Atom feed
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




  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