unsigned becomes signed in if-statement comparisons?

独自空忆成欢 提交于 2019-11-29 06:54:43

In the expression:

if( (u16_varLow - u16_varHigh) > (unsigned short)5 )  

(u16_varLow - u16_varHigh) will be promoted to an int and evaluate to -65525. The fix for your problem is to cast to an unsigned type, like you do in the "Does enter"-code.

The reason s16_Res1 = u16_varLow - u16_varHigh; yields 11 is that the result of the subtraction, -65525, doesn't fit in a short.

In the other answers we have seen that

u16_varLow - u16_varHigh

for you (with 16 bit short and 32 bit int) is equivalent to

(int)u16_varLow - (int)u16_varHigh

and thus its result is the int value -65525. Thus the assignment

s16_Res1 = u16_varLow - u16_varHigh; 

is equivalent to

s16_Res1 = -65525;

which in your case of 16 bit short yields "undefined behavior". You are just unlucky that your compiler decides to assign 11, instead. (Unlucky because I think that it is better to fail early.)

In contrast to that

u16_Res1 = -65525; 

is a valid assignment since u16_Res1 is of an unsigned type and arithmetic of unsigned types is modulo the appropriate power of two.

In the "usual arithmetic conversions", types smaller than int are promoted to either int or unsigned int before they are used in most expressions. The rule is that if int can represent all the values of the smaller type, then it is promoted to int; otherwise it is promoted to unsigned int. This is often considered something of a wart, because in many cases it causes unsigned char and unsigned short values to be promoted to int.

This is exactly what you're seeing - u16_varLow and u16_varHigh and (unsigned short)5 are all promoted to int before the subtraction and comparison, which then happen using int. If you wish to be certain that an expression will use unsigned arithmetic, you must do it in unsigned int, not unsigned short:

if( ((unsigned)u16_varLow - (unsigned)u16_varHigh) > 5U )

The first one, if( (u16_varLow - u16_varHigh) > (unsigned short)5 ) will never pass, as (u16_varLow - u16_varHigh) returns negative number, because it's treated as an integer. The second one casts the same negative number, to unsigned short, that's why it passes.

Note - you know that all this is platform-dependent, right? The size of short, int, etc. depends on the concrete platform.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!