This code doesn't compile and it should:
void main()
{
byte x, y, z;
short a = x+y;
}
Although the manifest type of x+y is int, the actual range of x+y, regardless of the values of x and y, is -byte.min-byte.min to byte.max+byte.max. That range fits properly in a short so the compiler should let the code go through.
Comment #1 by sandford — 2009-07-07T08:07:25Z
Additionally, propagation doesn't work for
byte, ubyte, bool and char.
for operations + * - / % >>
Also
byte x,y;
short z;
z = x<<1; // Error: cannot implicitly convert expression (cast(int)x << 1) of type int to byte
z = x << y; // compiles
// Repeat for >>>
Also
ubyte x,y=10;
ubyte z;
z = -y; // compiles
Inconsistancies:
byte x,y;
short z;
z += x; //compiles, z = z + x doesn't
x += y; //compiles, x = x + y doesn't
x++; //compiles, x = x+1, doesn't
++x; //compiles, x = x+1, doesn't
x = x + 1; // Error: cannot implicitly convert expression (cast(int)x + 1) of type int to byte
// Again repeat for the other operations/type combos
also
byte[] x, y, z;
z[] = x[] * z[]; //compiles
// repeat for other array operation and type combos
Comment #2 by dfj1esp02 — 2010-11-16T13:40:52Z
Some asserts for modulus and shifts
---
byte b;
short s;
int i;
long l;
static assert(is(typeof(s%b)==byte));
static assert(is(typeof(i%s)==short));
static assert(is(typeof(b<<b)==int));
static assert(is(typeof(b>>i)==byte));
static assert(is(typeof(b>>>b)==byte));
static assert(is(typeof(b>>l)==byte));
---
Comment #3 by andrei — 2010-11-16T13:54:16Z
The point is not to ascribe the smallest static type to the result. That would break compatibility with C in many ways. All that happens is the compiler tracks the range of the expression statically while using the same typing rules as C.
Comment #4 by dfj1esp02 — 2010-11-16T14:01:34Z
---
l = cast(int)(s%b);
l = cast(short)(s%b);
---
What's the difference?
Comment #5 by dfj1esp02 — 2010-11-16T14:22:01Z
In any case
---
static if(__traits(compiles, s=b+b))
{
static assert(__traits(compiles, b=s%b));
static assert(__traits(compiles, s=s>>b));
static assert(__traits(compiles, s=s>>>b));
}
---
Comment #6 by dfj1esp02 — 2010-11-16T22:03:08Z
There should be ints in shift asserts
---
static if(__traits(compiles, s=b+b))
{
static assert(__traits(compiles, b=i%b));
static assert(__traits(compiles, b=b>>i));
static assert(__traits(compiles, b=b>>>i));
}
---