Pirx un[blog]ged

Mike is reading four blogs. This is none of them.

You have been warned

The C++ compiler helps us to avoid to initialize a variable with the wrong type or a value out of range:

char b = {0x7f};    //  OK
char c = {0x80};    //  warning C4309: 
//  'initializing' : truncation of constant value

VC complains that value 0x80 must be truncated to fit into a variable of type char. This isn't the full truth. In fact the same bit pattern gets a different interpretation. The bit sequence 1000 0001 is 129 in the world of unsigned characters and -127 for signed characters. There is no difference on the bit/byte level. And yet there is a great difference. You cannot ignore this warning:

char c = {0x80};    
if (c == 0x80)  {
    std::cout << "OK" << std::endl; 
}
else    {
    std::cout << "Matrix is broken" << std::endl;
}

If you run this code you can clearly see, the matrix is broken. This happens because the literal 0x80 is of type int. When attempting to compare both values, variable c will be converted into an unsigned int. And here is where the magic happens, the result is FFFFFF80, which is quit different from 0x80.

You have been warned. But in certain cases you/we fall into the trap without any prior warning. Look at the following code snippet:

char ca[ 2 ] = { 0x7F, 0x7F };

++ca[1];

if ( ca[1] == 0x80 ) {
    std::cout << "OK" << std::endl; 
} else {
    std::cout << "Matrix is broken" << std::endl;
}

The matrix is broken again and no one has warned you. No one could you warn, because the evil occurred at runtime. Believe me, I wouldn't write about this if it would be a trivial matter. It took me two hours to track such problem down some days ago. To fix the matrix use a simple static_cast and make your father proud:

if (c == static_cast < char > (0x80))   {
    std::cout << "OK" << std::endl; 
} else {
    std::cout << "Matrix is broken" << std::endl;
} 


comments powered by Disqus