digitalmars.D - Integer promotion...
- Oskar (40/40) Aug 26 2005 In both (32-bit int) C and D, i find working with 64 bit integer types t...
- Shammah Chancellor (9/53) Aug 26 2005 There was another thread about this which I think is related. It had to...
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?
Aug 26 2005
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
Aug 26 2005