Is it important to declare a variable as unsigned if you know it should never be negative? Does it help prevent anything other than negative numbers being fed into a function th
By using unsigned when signed values will not be needed, in addition to ensuring the datatype doesn't represent values below the desired lower bound, you increase the maximum upper bound. All the bit combinations that would otherwise be used to represent negative numbers, are used to represent a larger set of positive numbers.
It also keeps you from having to cast to/from unsigned whatever when interacting with other interfaces. For example:
for (int i = 0; i < some_vector.size(); ++i)
That will generally annoy the hell out of anyone who needs to compile without warnings.
This has value for the same reason that "const
correctness" has value. If you know that a particular value shouldn't change, declare it const
and let the compiler help you. If you know a variable should always be non-negative, then declare it as unsigned
and the compiler will help you catch inconsistencies.
(That, and you can express numbers twice as big if you use unsigned int
rather than int
in this context.)
One minor nicety is that it cuts down on the amount of array bounds checking testing that might be necessary... e.g. instead of having to write:
int idx = [...];
if ((idx >= 0)&&(idx < arrayLength)) printf("array value is %i\n", array[idx]);
you can just write:
unsigned int idx = [...];
if (idx < arrayLength) printf("array value is %i\n", array[idx]);
It does two things:
1) It gives you double the range for your unsigned values values. When "signed" the highest bit is used as the sign bit (1 means negative, 0 for positive), when "unsigned" you can use that bit for data. E.g., a char
type goes from -128 to 127, an unsigned char
goes form 0 to 255
2) It affects how the >>
operator acts, specifically when right shifting negative values.
There are two main things using unsigned
gives you
it allows you to use the right shift >>
operator safely on any value, as it can't be negative -- using a right shift on a negative value is undefined.
it gives you wrap-around mod 2^n arithmetic. With signed values, the effect of underflow/overflow is undefined. With unsigned values you get mod 2^n arithmetic, so 0U - 1U
will always give you the largest possible unsigned value (which will always be 1 less than a power of 2).