Universal integer or universal expression
Author Message
Universal integer or universal expression

Quote:

>In Ada 83, the following are all universal expressions:

Actually, it depends on the context whether they are universal.
E.g., in:

X: constant := +1;

"+1" is of type universal_integer, but in:

X: constant My_Int := +1;

+1 is of type My_Int (i.e. 1 is converted from universal_integer to
My_Int, and then the "+" operator of type My_Int is applied to it.)
This is all rather pedantic -- I'm not sure why you would care...

Quote:
>+1
>-1
>+1.0
>-1.0

>Has this changed in Ada 95?  Are these no longer the number one
>with the appropriate unary operation applied to it?

>It appears from the syntax summary that this has not changed.  Am I correct?

What exactly are you getting at?  I'm sure you don't suspect that "+1"
now means 2 in Ada 95.  ;-)

you can now say "for I in -1..+1 loop" (which was illegal in Ada 83).
Also, the exact rules for when implicit conversions of universal
expressions happen have changed, which eliminates Beujolais Effects, and
makes those rules easier to implement -- this change is obscure, and
will probably not affect real programs.  Also, static expressions are
evaluated exactly, even if the type is not universal, which was not true
in all compilers in Ada 83.  Maybe I could be more helpful if you
explained what it is you really want to know...

- Bob

Sat, 29 Nov 1997 03:00:00 GMT
Universal integer or universal expression

"+1
-1
+1.0
-1.0

Has this changed in Ada 95?  Are these no longer the number one
with the appropriate unary operation applied to it?

It appears from the syntax summary that this has not changed.  Am I correct?"

Yes, you are correct that they are numbers with an appropriate unary
operation, and yes, they are universal expressions, no contradicition here!

Sat, 29 Nov 1997 03:00:00 GMT
Universal integer or universal expression

Actually, it depends on the context whether they are universal.
E.g., in:

X: constant := +1;

"+1" is of type universal_integer, but in:

X: constant My_Int := +1;

+1 is of type My_Int (i.e. 1 is converted from universal_integer to
My_Int, and then the "+" operator of type My_Int is applied to it.)
This is all rather pedantic -- I'm not sure why you would care...

What exactly are you getting at?  I'm sure you don't suspect that "+1"
now means 2 in Ada 95.  ;-)

you can now say "for I in -1..+1 loop" (which was illegal in Ada 83).
Also, the exact rules for when implicit conversions of universal
expressions happen have changed, which eliminates Beujolais Effects, and
makes those rules easier to implement -- this change is obscure, and
will probably not affect real programs.  Also, static expressions are
evaluated exactly, even if the type is not universal, which was not true
in all compilers in Ada 83.  Maybe I could be more helpful if you
explained what it is you really want to know...

- Bob

What I am getting at is a potintial bug in GNAT.  The following code
should work if +10 is the universal integer 10 with the operator "+"
applied to it:

procedure Mod_Test is
type Mod_10 is mod 10;
A : Mod_10;
begin
A := +10;
end Mod_Test;

But, GNAT returns

mod_test.adb:5:09: value not in range of type "Mod_10" declared at line 2

the code

procedure Mod_Test is
type Mod_10 is mod 10;
A : Mod_10;
begin
A := -10;
end Mod_Test;

on the other hand, is correctly accepted by GNAT.

Sean McNeil

Sat, 29 Nov 1997 03:00:00 GMT
Universal integer or universal expression

Quote:

>What I am getting at is a potintial bug in GNAT.  The following code
>should work if +10 is the universal integer 10 with the operator "+"
>applied to it:

>procedure Mod_Test is
>   type Mod_10 is mod 10;
>   A : Mod_10;
>begin
>   A := +10;
>end Mod_Test;

No, it's not a gnat bug.  The universal integer 10 is implicitly
converted to Mod_10, and then the "+" of Mod_10 is applied to that
value.  The implicit conversion raises Constraint_Error by 4.6(28).
This is illegal by 4.9(34).

Note that the operators of a modular type reduce by the modulus (i.e.
they do "mod 10" for type Mod_10 -- see 3.5.4(20)), but literals are of
type universal_integer, so they don't reduce, and the implicit type
conversion does not reduce -- it raises C_E.  "A := 10;" would be
illegal, too, for the same reason.

I'm not sure exactly what you're trying to do, but note that you can
do things like this if you want:

X: Integer := 10;
Y: Mod_10 := Mod_10(X mod Mod_10'Modulus);

Quote:
>But, GNAT returns

>mod_test.adb:5:09: value not in range of type "Mod_10" declared at line 2

>the code

>procedure Mod_Test is
>   type Mod_10 is mod 10;
>   A : Mod_10;
>begin
>   A := -10;
>end Mod_Test;

>on the other hand, is correctly accepted by GNAT.

This is a gnat bug.  It is illegal for the same reason.

- Bob

Sat, 29 Nov 1997 03:00:00 GMT
Universal integer or universal expression

Quote:
>No, it's not a gnat bug.  The universal integer 10 is implicitly
>converted to Mod_10, and then the "+" of Mod_10 is applied to that
>value.

If this is so, then

x := 1 + 2 + 3 + 4 + 10;

causes the compiler to implicitly convert all the literals to a mod_10
type.  This means that the expression is evaluated differently depending
on the resultant type.  It seems excessive that the compiler needs to know
this.

Also, the integer operations do not work this way.

type int_10 is range 1 .. 10;
x : int_10 := 12 - 2;

is perfectly legal because the operands are not implicitly converted
to int_10 since the operator accepts int_10'base for it's arguments.

On the other hand, mod_10'base (is this a legal type?) has a range of
0 to the modulus-1.  It seems to me that limiting the range of a
modulus operator to mod_type'base as opposed to the way integer operations
are defined limits the ability for a compiler to defer doing the actual
modulus in certain cases (like the multiply addition above).  I have
not found anything in the RM to indicate how the arguments to modulus
operators are defined.

Quote:
>Note that the operators of a modular type reduce by the modulus (i.e.
>they do "mod 10" for type Mod_10 -- see 3.5.4(20)), but literals are of
>type universal_integer, so they don't reduce, and the implicit type
>conversion does not reduce -- it raises C_E.  "A := 10;" would be
>illegal, too, for the same reason.

That is exactly my point.  If +10 is 10 with the operator + applied to it,
then it should be "mod 10"'d.  You are saying the same thing, but claim
modulus operators only accept the range of the mod type as arguments.

Is there anywhere in the RM that actually defines the mod operators other
than saying they are like the integer operators?

Quote:
>I'm not sure exactly what you're trying to do, ...

It's not what I want to DO, but what I want to understand.

--

--  Please append a :-) to any and all comments as I am never serious.

Sat, 29 Nov 1997 03:00:00 GMT
Universal integer or universal expression

In Ada 83, the following are all universal expressions:

+1
-1
+1.0
-1.0

Has this changed in Ada 95?  Are these no longer the number one
with the appropriate unary operation applied to it?

It appears from the syntax summary that this has not changed.  Am I correct?

Sean McNeil

Sat, 29 Nov 1997 03:00:00 GMT
Universal integer or universal expression

Quote:

>>No, it's not a gnat bug.  The universal integer 10 is implicitly
>>converted to Mod_10, and then the "+" of Mod_10 is applied to that
>>value.

>If this is so, then

>  x := 1 + 2 + 3 + 4 + 10;

>causes the compiler to implicitly convert all the literals to a mod_10
>type.  This means that the expression is evaluated differently depending
>on the resultant type.  It seems excessive that the compiler needs to know
>this.

Excessive in what sense?  To much work for the compiler writer?
This is the same in Ada 83 -- the type of an expression depends
on its context -- that's always been a part of overload resolution.
And the rule about converting all the literals and then doing
the operations (as opposed to doing the operations, and then converting
the final result) is also the same as in Ada 83.

Quote:
>Also, the integer operations do not work this way.

^^^^^^^
Now called "signed integer" in Ada 95, to distinguish from "modular"
(which are also consider integer).

Quote:
>type int_10 is range 1 .. 10;
>x : int_10 := 12 - 2;

>is perfectly legal because the operands are not implicitly converted
>to int_10 since the operator accepts int_10'base for it's arguments.

12 and 2 are converted to the *type* of int_10.  I was a bit sloppy in
talking about converting to the modular type -- in the modular example,
the literals are converted to the *type* of mod_10, and the same thing
is true in the signed integer case.  But the values of a signed integer
type are the infinite set of integers.

Quote:
>On the other hand, mod_10'base (is this a legal type?) has a range of

It's a legal subtype.

Quote:
>0 to the modulus-1.  It seems to me that limiting the range of a
>modulus operator to mod_type'base as opposed to the way integer operations
>are defined limits the ability for a compiler to defer doing the actual
>modulus in certain cases (like the multiply addition above).

I don't understand.  Your examples are static, and so can be done at
compile time.

Quote:
> ...I have
>not found anything in the RM to indicate how the arguments to modulus
>operators are defined.

>>Note that the operators of a modular type reduce by the modulus (i.e.
>>they do "mod 10" for type Mod_10 -- see 3.5.4(20)), but literals are of
>>type universal_integer, so they don't reduce, and the implicit type
>>conversion does not reduce -- it raises C_E.  "A := 10;" would be
>>illegal, too, for the same reason.

>That is exactly my point.  If +10 is 10 with the operator + applied to it,
>then it should be "mod 10"'d.  You are saying the same thing, but claim
>modulus operators only accept the range of the mod type as arguments.

No, it's just the literal that's wrong.  The "+" operator does the mod
operation, as you say.  Don't forget that there are many "+" operators
-- the one for universal_integer does something different from the one
for a modular type.

Quote:
>Is there anywhere in the RM that actually defines the mod operators other
>than saying they are like the integer operators?

3.5.4(20).  Otherwise, they're the same.

- Bob

Sat, 29 Nov 1997 03:00:00 GMT
Universal integer or universal expression

Sean, I really think it is better if you send a message to gnat-report
when you find something like this. We will tell you if we think it is a bug
or an Ada 95 feature, and explain why. Then if you don't like this
explanation, then you can post to CLA and start a discussion.

Otherwise, we get this situation where a lot of unnecessary confusion is
generated by posts that imply incompatibilities and peculiarities that
do not exist!

Sat, 29 Nov 1997 03:00:00 GMT
Universal integer or universal expression

: In Ada 83, the following are all universal expressions:

: +1
: -1
: +1.0
: -1.0

Actually, these are only universal expressions in Ada 83 if
the context does not force them to be of some nonuniversal type.

: Has this changed in Ada 95?  Are these no longer the number one
: with the appropriate unary operation applied to it?

The net effect has not changed, but the explanation for it has
changed a bit.  In the absence of a context that forces these
to be of some other type, these are preferentially considered
to be of a "root" numeric type (either root integer or root real).

: It appears from the syntax summary that this has not changed.  Am I correct?

One change is that you can now use negative numbers in "anonymous"
array bounds and for loops.  This was not allowed in Ada 83.
In particular, the following is legal in Ada 95 but considered

for I in -1 .. 10 loop
...
end loop;

: Sean McNeil

Intermetrics, Inc.

Sun, 30 Nov 1997 03:00:00 GMT
Universal integer or universal expression

Quote:

>Sean, I really think it is better if you send a message to gnat-report
>when you find something like this. We will tell you if we think it is a bug
>or an Ada 95 feature, and explain why. Then if you don't like this
>explanation, then you can post to CLA and start a discussion.

>Otherwise, we get this situation where a lot of unnecessary confusion is
>generated by posts that imply incompatibilities and peculiarities that
>do not exist!

There is already alot of confusion in this area.  I am attempting to
discover the underlying reasoning of Ada 95 in this area.  I only
mentioned GNAT because it is inconsistent in it's implementation, but
it is not a GNAT issue I am struggling with.  It is the definition
of modular operations and implicit conversion of arguments to these
operators.

have incorrectly defined the modular types.  In discussions on how this
area should be clarified some interesting things have come up.  Here is
yet again another example:

x : constant := -10;
y : mod_10 := mod_10(x mod mod_10'Modulus);

is a fine peice of code, but pretty ugly.  I'd prefer to be able to write

y : mode_10 := + x;

even though it looks a little odd.

Again, this has nothing to do with GNAT other than whatever the resolution,
a gnat-report will be made regarding the inconsistency.  I don't want to
turn this into a debate about GNAT.  This is a discussion of Ada 95 and
mod types.

I am sorry if I have implied any incompatabilities, that was not my intent.
I am not sorry about the peculiarity, because if mod types do require the
arguments to be within range of the desired resultant type, then it is
not consistent with the integer operations and this is peculiar to me.

So, what does Ada 95 say about the arguments to mod operators?

--

--  Please append a :-) to any and all comments as I am never serious.

Sun, 30 Nov 1997 03:00:00 GMT
Universal integer or universal expression

Quote:

>There is already alot of confusion in this area.  I am attempting to
>discover the underlying reasoning of Ada 95 in this area.  I only
>mentioned GNAT because it is inconsistent in it's implementation, but
>it is not a GNAT issue I am struggling with.  It is the definition
>of modular operations and implicit conversion of arguments to these
>operators.

>have incorrectly defined the modular types.

You mean text book authors?  The language design changed in this area
fairly late, so it could be that some authors were working from an
earlier version.

Quote:
> ...In discussions on how this
>area should be clarified some interesting things have come up.  Here is
>yet again another example:

>x : constant := -10;
>y : mod_10 := mod_10(x mod mod_10'Modulus);

>is a fine peice of code, but pretty ugly.  I'd prefer to be able to write

>y : mode_10 := + x;

>even though it looks a little odd.

Why not "y : mod_10 := 0;"?

I guess it's a trade-off between writing something short, versus
catching potential errors.  Clearly, this is wrong:

type T is range 1..10;
X: T := 11; -- Wrong.

Fine, you get an error for this.
Now what do you want for this:

type M is mod 10;
X: M := 10;

Should X be assigned zero?  Most likely, the program is wrong,
and it's better to get an error.  If you really meant zero,
you can say so more explicitly.

BTW, I'm confused as to why you think "y : mod_10 := + x;"
ought to be different from "y : mod_10 := x;".

Quote:
>Again, this has nothing to do with GNAT other than whatever the resolution,
>a gnat-report will be made regarding the inconsistency.  I don't want to
>turn this into a debate about GNAT.  This is a discussion of Ada 95 and
>mod types.

>I am sorry if I have implied any incompatabilities, that was not my intent.

It would be hard to claim that there are incompatibilities with Ada 83
modular types, since Ada 83 didn't have modular types!  ;-)

Quote:
>I am not sorry about the peculiarity, because if mod types do require the
>arguments to be within range of the desired resultant type, then it is
>not consistent with the integer operations and this is peculiar to me.

It's not the operators that are giving you the error.  The operators
wrap around.  It's just type conversions that give the error you are
worrying about.  And integer literals and named numbers get implicitly
converted, so they invoke the type conversion rule.

Quote:
>So, what does Ada 95 say about the arguments to mod operators?

By the time any operator is invoked, its arguments will necessarily be
in range.

Quote:
>--  Please append a :-) to any and all comments as I am never serious.

Oh, well, then never mind.  ;-)

- Bob

Sun, 30 Nov 1997 03:00:00 GMT
Universal integer or universal expression

I would like to appologize for the "immense :-)" mess I have made
of this thread.  With the patient help of Robert A Duff, I am pretty
sure I have things straight now.  I would like to express my thanks
for his explanations.

Once I am 100% certain I comprehend my basic misunderstanding,
I'll post the information that finally fixed my noggin.  Next time,
I'll take the discussion off-line sooner until things are resolved.

Thanks to everyone.

Sean McNeil

Sun, 30 Nov 1997 03:00:00 GMT
Universal integer or universal expression

Quote:
> >Also, the integer operations do not work this way.
>            ^^^^^^^
> Now called "signed integer" in Ada 95, to distinguish from "modular"
> (which are also consider integer).

This terminology has some potential for confusion.  Note, for example,
that this:

type Byte is range 0 .. 255;

creates a signed integer type.

(Of course, if you want an unsigned byte type, it's probably better to
declare it as

type Byte is mod 256;

if you don't need Ada 83 compatibility.)

--

TeleSoft^H^H^H^H^H^H^H^H Alsys^H^H^H^H^H Thomson Software Products
10251 Vista Sorrento Parkway, Suite 300, San Diego, CA, USA, 92121-2718
That's Keith Thompson *with* a 'p', Thomson Software Products *without* a 'p'.

Sun, 30 Nov 1997 03:00:00 GMT
Universal integer or universal expression

Quote:

>    type Byte is range 0 .. 255;

>creates a signed integer type.

Yes.

Quote:
>(Of course, if you want an unsigned byte type, it's probably better to
>declare it as

>    type Byte is mod 256;

>if you don't need Ada 83 compatibility.)

Not necessarily.  It depends what you're doing.  In the first case, you
get range checking.  In the second case you get wrap-around, plus
bit-wise logical operators.  Thus, the modular type facility is (IMHO)
somewhat lower level.  If you just want a number that happens to range
from 0 to 255, the signed integer type seems best to me.  If you want
wrap-around arithmetic, or bit-wise operators, then the modular type is
best.

Note that in both of the above examples, Byte'Size should be 8.

- Bob

Sun, 30 Nov 1997 03:00:00 GMT
Universal integer or universal expression

Quote:
> >(Of course, if you want an unsigned byte type, it's probably better to
> >declare it as

> >    type Byte is mod 256;

> >if you don't need Ada 83 compatibility.)

> Not necessarily.  It depends what you're doing.  In the first case, you
> get range checking.  In the second case you get wrap-around, plus
> bit-wise logical operators.  Thus, the modular type facility is (IMHO)
> somewhat lower level.

If you want an unsigned byte type, you probably want the lower-level
facilities.  Few other situations are likely to happen to require a
range of 0..255.  (There are always counterexamples, of course.)

--

TeleSoft^H^H^H^H^H^H^H^H Alsys^H^H^H^H^H Thomson Software Products
10251 Vista Sorrento Parkway, Suite 300, San Diego, CA, USA, 92121-2718
That's Keith Thompson *with* a 'p', Thomson Software Products *without* a 'p'.

Mon, 01 Dec 1997 03:00:00 GMT

 Page 1 of 2 [ 22 post ] Go to page: [1] [2]

Relevant Pages