In the line:
for (carry = bin[i], j = size - 1; (j > high) || carry; --j)
my analysis missed that the compare (j > high) is always true when
high is 0 and j wraps around. So although the loop does not store
through a negative 'j' offset, it does require j to become negative
in order to terminate the loop in that case. My apologies.
size can only be positive (and non-zero) as it is set to a positive expr + 1.
high is initialised with size-1 which is never negative, and then set to j at
the end of each loop iteration. It therefore can only be negative if j can.
The heart of the loop assigns to buf[j] which is on the stack. If j can become
negative during the loop then this is clearly undefined behaviour.
Following the loop, high is unused and j is reset to 0 and only incremented.
Thus both variables can be declared unsigned, and sys/types.h removed since
there are no more ssize_t variables remaining. This removes the last two sign
compare warnings from this file.
zcount can only ever be positive as it starts from 0 and is incremented.
i can only be positive as it starts from zcount and is incremented. This
removes one of three sign compare warnings in this function.