This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
handy.h: Make inRANGE more robust
It turns out that in order to make this work or assert if it won't, it
needs to be more complicated. The problem has to do with signed and
unsigned operands. It now special cases where the item being checked to
be in the range is a char, and casts that to a U8. Otherwise, there is
a problem when that is a negative signed type and the range is above the
int_max for that type. An assert is added to detect this rare event
(not rare for chars, hence the special case). The use of sizeof() for
this case means that it will be resolved at compile time and not
generate extra code. I did an experiment, and gcc even under -O0
compiled away the sizeof() clause.
As an example of why this is needed, suppose we have a signed char,
-127, and we want to see if it is in the range 128-130, expressed as
ints. Without casting that -127 to an unsigned char, it would subtract
128 from -127, yield -255, which when cast to an unsigned int would be
wrong. But casting the -127 to U8 first yields 129, and gives the
correct result. The same issue could happen wih ints if the range is
above INT_MAX, but that is a much rarer case, and this macro asserts
against it.