In some C99 code, I need to check whether variable i
is in the interval [0, max]
where max
is known to be positive. The problem is that the type of the variable is allowed to be both signed and unsigned (by changing a typedef
). How does one best check that the variable is in the interval?
The straightforward approach would be:
bool is_in_interval(my_type i, my_type max) {
assert(max > 0);
return (i >= 0 && i <= max);
}
This will work fine when we have typedef int my_type;
. But when my_type
is unsigned (i.e., typedef unsigned int my_type;
), i >= 0
is always true and compilers will (rightly) warn for it, which I want to avoid. (I don't want to turn off that warning since it's useful when such comparisons actually are unintended, and just ignoring compiler warnings is not a good idea.)
My current idea is to cast i
to an unsigned type and just check the upper bound:
bool is_in_interval(my_type i, my_type max) {
assert(max > 0);
return ((size_t) i <= (size_t) max);
}
If the signed type has a two's complement representation, any negative value should be greater than max
once cast to the unsigned version, right? If so, this should work. I'm, however, uncertain whether this is an advisable approach. Is it, for example, safe to assume that signed types use two's complement on all platforms? Is there some better way to do this?