I did an interesting test on the type conversion between int and unsigned long. the results is like the following:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
#include <iostream>
#include <limits>
using namespace std;
int main() {
int ival(-100);
unsigned long ulval1(numeric_limits<unsigned long>::max());
unsigned long ulval2(10);
cout<<ulval1<<endl;
cout<<sizeof(ival+ulval1)<<endl;
cout<<ival+ulval1<<endl;
cout<<sizeof(ival+ulval2)<<endl;
cout<<ival+ulval2<<endl;// I am expecting -90 here
return 0;
}
|
1 2 3 4 5
|
18446744073709551615
8
18446744073709551515
8
18446744073709551526
|
what I want to say is, there can be several conditions for adding a signed int to an unsigned long:
1: if the ival is positive, then adding a positive to a positive, both value should be converted to unsigned long, which is reasonable, even when the sum is larger than the max limit of unsigned long, because user himself should be ware of that the sum value may be too large and will be modulo into the range of unsigned long.
2: if the ival is negative, but the sum is positive, then both sum and ulval can fit in unsigned long, so we should convert them into unsigned long
3: this is the interesting one:
if the ival is negative, and the sum is also negative, that means the ulval's real value can actually fit in int range, so the compiler should convert it to int, so as to preserve the value. but compiler didn;t do this to comply it's "preserving value" rule.
Am I right? thanks!