August 26, 2005 Integer promotion... | ||||
---|---|---|---|---|
| ||||
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? |
August 26, 2005 Re: Integer promotion... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Oskar | 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? There was another thread about this which I think is related. It had to do with 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 |
Copyright © 1999-2021 by the D Language Foundation