Mixing operations with signed and unsigned types

Stewart Gordon smjg_1998 at yahoo.com
Tue Jun 29 16:30:19 PDT 2010

Michal Minich wrote:
> I was surprised by the behavior of division. The resulting type of 
> division in example below is uint and the value is incorrect. I would 
> expect that when one of operands is signed, then the result is signed 
> type. 

Going by the spec
"Usual Arithmetic Conversions"
the compiler is behaving correctly.  But see below....

> auto f = a - b           // uint, 4294967288
> auto g = a + b           // uint, 4294967292
> auto h = a < b           // bool, false
> auto i = a > b           // bool, true
> Recently while I was hunting some bug in templated code, I created a 
> templated function for operator <, which requires both arguments to be 
> either signed or unsigned.

It is in fact a bug that DMD accepts it.

> Fortunately D such function was quite easy to 
> do, if it wasn't possible I don't know if I would ever find form where 
> the ints and uints come from...
> bool sameSign (A, B) () {
>     return isUnsigned!(A) && isUnsigned!(B)) || (isSigned!(A) && isSigned!
> (B);
> }
> bool lt (A, B) (A a, B b) {
>     static assert (sameSign!(A, B) ());
>     return a < b;
> }
> Could somebody please tell me why is this behavior, when mixing signed 
> and unsigned, preferred over one that computes correct result.

It would appear to be Walter's idea of C compatibility taking control 

> If this cannot be changed, is it possible to just make compiler 
> error/warning when such incorrect calculation could occur. If it is 
> possible in D code to require same-signed types for function, it is 
> definitely possible for compiler to require explicit cast in such 
> cases.

I agree.  Either behave sensibly or generate an error.


More information about the Digitalmars-d-learn mailing list