## digitalmars.D - Integer promotion...

• Oskar (40/40) Aug 26 2005 In both (32-bit int) C and D, i find working with 64 bit integer types t...
```In both (32-bit int) C and D, i find working with 64 bit integer types to be
problematic because of the integer promotion rules. How would a 64-bit D handle
this? Will integer operands be promoted to 64bit?

I tripped on this today:

long a = rand()%10 - 5;
assert(a < 100); // FAILS 50% of the time

changing long -> int makes the assert valid.

I know why this happens (5 is cast into uint). It is the same way it works in C.
More cases:

ubyte test1() { return 1; }
uint  test2() { return 1; }
ulong test3() { return 1; }

void main() {
int  a = test1() - 2;
long b = test1() - 2;
int  c = test2() - 2;
long d = test2() - 2;
int  e = test3() - 2;
long f = test3() - 2;
assert(a < 0); // OK
assert(b < 0); // OK
assert(c < 0); // OK
assert(d < 0); // FAILS
assert(e < 0); // OK
assert(f < 0); // OK
}

Is there anything I can do to help me avoid making such errors? :)

Why are integer operands converted to unsigned rather than signed when their
sizes match? (I'm sure there are good reasons.)

Is there any way to introduce a warning to help finding this problem, without
introducing warnings all over the place in old and correct code?

Also, why is there no warning at conversion from uint to int when there is from
ulong to long? Like here:

uint  test1 () { return 1; }
ulong test2 () { return 1; }

void main() {
int   a = test1() - 2;   // NO WARNING
long  b = test2() - 2L;  // WARNING: conversion ulong -> long
}

Is that because (int) = (int) + (ubyte) and similar are too common?
```
Aug 26 2005
```In article <denad2\$1e8u\$1 digitaldaemon.com>, Oskar says...
In both (32-bit int) C and D, i find working with 64 bit integer types to be
problematic because of the integer promotion rules. How would a 64-bit D handle
this? Will integer operands be promoted to 64bit?

I tripped on this today:

long a = rand()%10 - 5;
assert(a < 100); // FAILS 50% of the time

changing long -> int makes the assert valid.

I know why this happens (5 is cast into uint). It is the same way it works in C.
More cases:

ubyte test1() { return 1; }
uint  test2() { return 1; }
ulong test3() { return 1; }

void main() {
int  a = test1() - 2;
long b = test1() - 2;
int  c = test2() - 2;
long d = test2() - 2;
int  e = test3() - 2;
long f = test3() - 2;
assert(a < 0); // OK
assert(b < 0); // OK
assert(c < 0); // OK
assert(d < 0); // FAILS
assert(e < 0); // OK
assert(f < 0); // OK
}

Is there anything I can do to help me avoid making such errors? :)

Why are integer operands converted to unsigned rather than signed when their
sizes match? (I'm sure there are good reasons.)

Is there any way to introduce a warning to help finding this problem, without
introducing warnings all over the place in old and correct code?

Also, why is there no warning at conversion from uint to int when there is from
ulong to long? Like here:

uint  test1 () { return 1; }
ulong test2 () { return 1; }

void main() {
int   a = test1() - 2;   // NO WARNING
long  b = test2() - 2L;  // WARNING: conversion ulong -> long
}

Is that because (int) = (int) + (ubyte) and similar are too common?

typedefs.  In that issue
(Stewart was the discoverer, check his recent posts.)  the returned value took
on the type of the left
hand value.

You might test this:

long d = test2() - 2;
assert(d < 0); // FAILS

---->

long d = -2 + test2();
assert(d < 0); // FAILS

-Sha
```
Aug 26 2005