Thread overview
Behaviour of unsigned cast
Apr 10, 2007
Henning Hasemann
Apr 10, 2007
Dan
Apr 10, 2007
Frits van Bommel
Apr 10, 2007
David B. Held
Apr 10, 2007
Dan
April 10, 2007
I've had several issues with this implicit cast unsigned and already posted some here (the "is this inteded behaviour" is also a good example).

Now it has come to my mind that no matter if you like the implicity of such
a cast it is a bit strange that cast(uint)some_int in fact is a
*reinterpretation* of the same binary data whereas other casts (for example
cast(int)some_float) look at the meaning of the value and try
to find something close in the new type.

cast(uint) (and equivalents for other numeric types) is the only cast
I know of that does change meaning of the value in such a hard way
(all other casts that I'm aware of try to preserve meaning).

Im *not* saying it would be wise to have cast(uint) throw a runtime
error when it is called on a negative value (though there are situations
when this might be useful).
But maybe the compiler should warn whenever cast(uint) is used
(especially when this happens implicitly).

Henning

April 10, 2007
Henning Hasemann Wrote:
> Im *not* saying it would be wise to have cast(uint) throw a runtime
> error when it is called on a negative value (though there are situations
> when this might be useful).
> But maybe the compiler should warn whenever cast(uint) is used
> (especially when this happens implicitly).

Walter so far has always tried not to use warnings.  I agree with his reasons.

I think it's okay to cast an int to a uint implicitly *only* if the number is known to be positive.  Otherwise you're violating the semantics (value) of the number by casting it, and it should be explicit.

Ultimately, this again comes down to proveable bounds checking, as you can't necessarily cast a uint to an int because of the case int.max..uint.max

Somehow I don't see how cmp EAX, EBX knows what sign the operands are.
April 10, 2007
Dan wrote:
> Somehow I don't see how cmp EAX, EBX knows what sign the operands are.

It doesn't.
"cmp" sets several flags, among others the carry (CF) and overflow (OF) flags. CF being 1 means that if the operands were unsigned there was an overflow condition. OF being 1 means that if they were signed there was an overflow condition. (Note that "cmp" is basically a non-modifying "sub", so "overflow" here means that EAX < EBX)
If the program wants to know whether an overflow occurred it needs to check the value of the appropriate flag, typically using an appropriate conditional instruction (often a jump).
Note that there is no such flag intended for mixed-signedness comparisons.
April 10, 2007
Frits van Bommel wrote:
> Dan wrote:
>> Somehow I don't see how cmp EAX, EBX knows what sign the operands are.
> 
> It doesn't.
> "cmp" sets several flags, among others the carry (CF) and overflow (OF) flags. CF being 1 means that if the operands were unsigned there was an overflow condition. OF being 1 means that if they were signed there was an overflow condition. (Note that "cmp" is basically a non-modifying "sub", so "overflow" here means that EAX < EBX)
> If the program wants to know whether an overflow occurred it needs to check the value of the appropriate flag, typically using an appropriate conditional instruction (often a jump).
> Note that there is no such flag intended for mixed-signedness comparisons.

So what do you guys think of mixed-sign arithmetic?  +, - , *, /, etc? Does it cause you problems, or too convenient to give up?

Dave
April 10, 2007
David B. Held Wrote:
> So what do you guys think of mixed-sign arithmetic?  +, - , *, /, etc? Does it cause you problems, or too convenient to give up?

It doesn't cause *me* problems because I only use unsigned values for loop inc/dec, enums, and such.  I almost only ever use signed for numbers where the point is that it's a number.

I've already said my opinion is that unsigned/signed math should be explicitly cast.