4 ms·
Why Not Mix Signed and Unsigned Values in C/C++?
- junkbit 16y agoI saw the sign and it opened up my mind
- mfukar 16y agoUnsigned integer types are needed for well defined modular arithmetic, and signed integer types are needed for, well, negative values of β.
- pietrofmaggi 16y agoSigned integer types are,for example, native number format of ARM asm. If you use unsigned the compiler has to introduce conversion for you. So your best bet is to always use signed int, excluding when they're not appropriate ;-) The real problem, well, what you have to always take in account, is the "behind the scene" type promotion that any C Compiler has to do. To cope with this you can put a lot of unnecessary type cast in the code (like when you add parentesis to formulas just to make clear what is the operator precedence), but this add a lot of clutter to the code.
- mfukar 16y agoSo your best bet is to always use signed int, excluding when they're not appropriate ;-) Exactly, that's why both types are needed. However, when it comes to mixing or using them interchangeably in code, type casts are usually the best indicator that something is wrong, and a code review is necessary.
- mansr 16y agoARM handles signed and unsigned numbers equally. Addition and subtraction are the same operation whether signed or unsigned. Multiplication of 32-bit numbers with 64-bit result has both signed and unsigned versions. Condition codes can test for both signed and unsigned relations. As for the real problem, you are right on the mark. Mixing signed and unsigned can result in a negative number being interpreted as a large positive number with unpleasant consequences. However, casts will rarely remedy this in a safe manner since unsigned to signed conversion where the value is outside the range of the target type is unspecified by the C standard.
- pietrofmaggi 16y ago"ARM handles signed and unsigned numbers equally." Yep, you are right. I wrote this in a hurry and forget that what I was thinking about was arguments passing in functions. C compilers has to "trim values" if the parameter are not signed int.
- mansr 16y agoWrong again. Function parameters are passed as if the values were assigned to variables of the corresponding types using the usual implicit conversion rules. If the function parameter has type of different width than the value being passed, a truncation or sign/zero extension happens. A signed value assigned to an equal-width unsigned parameter retains the same bit pattern (in 2's complement). Unsigned to signed conversion is potentially unspecified (out of range values). All known ARM compilers convert from unsigned to signed by keeping the bits unchanged. In no case does the signedness of parameters affect the speed of the compiled code (on ARM).
- pietrofmaggi 16y agoYep^2 Thanks for remembering this. Time to take a break for today.
- pietrofmaggi 16y agoNow with a bit more of time, just for sake of completeness (from the ARM's System Developers Guide). "If your code uses addition, subtraction, and multiplication then there's no performance difference between signed and unsigned operation. However, there is a difference when it comes to division." Consider the following short example that averages two integers: int average_v1(int a, int b) { return (a+b)/2; } This compiles to: average_v1 ADD r0, r0, r1 ; r0 = a+ b ADD r0, r0, r0, LSR #31 ; if (r0<0) r0++ MOV r0, r0, ASR #1 ; r0 = r0 >> 1 MOV ro, r14 ; return ro Notice that the compiler adds one to the sum before shifting by right if the sum is negative. In other words it replaces x/2 by the statement: (x<0)?((x+1)>>1):(x>>1) It must do this because x is signed. In C on an ARM target, a divide by two is not a right shift if x is negative. For example, -3 >> 1 = -2 but -3/2 = -1. Division rounds towards zero, but arithmetic right shift rounds towards -inf. It is more efficient to use unsigned types for division. The compiler converts unsigned power of two divisions directly to right shifts. For this and other fancy ARM insight take a look at the ARM System Developer's Guide, really a nice book: http://www.elsevier.com/wps/find/bookdescription.cws_home/702211/description#description http://www.elsevier.com/wps/find/bookdescription.cws_home/70...