Why are some implicit type conversions safe on the machine and not on the other? How can I prevent cross platform issues?

I recently discovered an error in my code that took several hours to debug.

the problem was a function defined as:

unsigned int foo(unsigned int i){
   long int v[]={i-1,i,i+1} ;
       .
       .
       .
 return x ; // evaluated by the function but not essential how for this problem.
}

The definition of v did not cause any problems on my development machine (ubuntu compiler 12.04 32 bit, g ++), where unsigned ints were implicitly converted to long ints and as such negative values ​​were correctly processed.

On another machine (ubuntu 12.04 64 bit, g ++ compiler), however this operation was not safe. When I = 0, v [0] was not set to -1, but to some strange big value (as is often the case when trying to make unsigned int negative).

I could solve the problem by setting the value i to long int

long int v[]={(long int) i - 1, (long int) i, (long int) i + 1};

( ).

, .

, ?

+5
2

unsigned / , 0U-1 - std::numeric_limits<unsigned>::max().

, , , . , , , ( ).

, long 64- (, 64- ), unsigned .

long 32- 32- , , -1.

: - . , ? , .

g++ ( , 4.5) -Wsign-conversion, .

+6

:

template<typename O, typename I>
O architecture_cast(I x) {
/* make sure I is an unsigned type. It  */
static_assert(std::is_unsigned<I>::value, "Input value to architecture_cast has to be unsigned");

assert(x <= static_cast<typename std::make_unsigned<O>::type>( std::numeric_limits<O>::max() ));

return static_cast<O>(x);
}

, , . unsigned int, 0, -1, int.

0

All Articles