Casting up to ints...

Don Clugston dac at nospam.com.au
Tue May 2 01:35:50 PDT 2006


Unknown W. Brackets wrote:
> One thing I've never liked, or completely understood, was the way 
> arithmetic casts up to ints - but no higher.  Don't get me wrong, I 
> don't at all mind it going from a short to an int... but why can't it go 
> farther?
> 
> If I add two ubytes into a ulong, I get the correct result.
> 
> If I add two uints into a ulong, I get an incorrect result.
> 
> I realize this is because the + operator yields an int/uint result 
> unless one of the values is a long/ulong.  But, since this doesn't 
> happen for bytes and shorts, it seems terribly inconsistent.
> 
> And when you usually deal in small numbers, you get used to numeric 
> overflows not happening without having to cast.  Then you deal with some 
> large numbers, and create a bug.  This is why I think consistency in 
> programming is so important.
> 
> So, all I'm asking is... why?  I mean, what is the reason for this 
> behavior?  Is it just because, that's how C did it?  Or is there a 
> greater reason I'm missing?

There are very strong practical reasons. Basically it's because D 
targets 32-bit CPUs, and there is no performance cost to converting 
everything to 'int'. But converting everything to 'long' would be a 
massive performance hit on a 32-bit CPU. Even the x86-64 uses 32 bit 
arithmetic most of the time.

It's extremely rare to find situations where ints overflow. int.max is 
an enormous number. This is emphatically not the case for short.max and 
byte.max.

> 
> Otherwise it just seems like a case where we have to use the blunt 
> instrument that is casting to make the compiler do something which is 
> completely logical to humans.
> 
> Thanks,
> -[Unknown]
> 
> PS: For those of you who need code to understand my question:
> 
> import std.stdio;
> 
> int main()
> {
>     ulong l1, l2;
> 
>     ubyte b1 = ubyte.max, b2 = ubyte.max;
>     uint i1 = uint.max, i2 = uint.max;
> 
>     l1 = b1 + b2;
>     l2 = i1 + i2;
> 
>     // l1 will be "right", l2 will be "wrong".
>     writefln("Without casting:");
>     writefln("ubyte + ubyte = %d\n\t(%d * 2)", l1, ubyte.max);
>     writefln("uint + uint = %d\n\t(%d * 2)", l2, uint.max);
> 
>     l1 = cast(ulong) b1 + cast(ulong) b2;
>     l2 = cast(ulong) i1 + cast(ulong) i2;
> 
>     // l1 and l2 will both be "right".
>     writefln("With casting:");
>     writefln("ubyte + ubyte = %d\n\t(%d * 2)", l1, ubyte.max);
>     writefln("uint + uint = %d\n\t(%d * 2)", l2, uint.max);
> 
>     return 0;
> }



More information about the Digitalmars-d mailing list