On 1/15/22 8:12 PM, Meredith Montgomery wrote:
...
> Interesting. I got another question here. If s[pos] is always a char
> and '0' is always a char, then s[pos] - '0' will never be greater than a
> char. It might be negative. If it's negative and if I do
Note that while members of the basic character set are required to be
represented by non-negative values (6.2.5p3), members of the extended
character set are not. If char is signed, they can be as low as
CHAR_MIN, in which case subtracting '0' necessarily results in undefined
behavior. The following discussion applies only when that isn't the case:
> (unsigner char) s[pos] - '0',
>
> can this do any wrapping at all? I'd say not in this case. I think you
> are in more general waters than I took your message. Can you clarify a
> bit? I'm a bit lost.
Subtraction involves (6.5p6) the usual arithmetic conversions
(6.3.1.8p1), and the first part of that is the integer promotions
(6.3.1.1p2). Both overflow and wrap-around are possible results, but
only on systems where CHAR_BIT >= 16. Such systems do exist - the ones
I've heard of are embedded systems specialized for digital signal
processing.
If all values of type unsigned char can be represented as an int,
(unsigned char)s[pos] will be promoted to int before performing the
subtraction (6.3.1.1p2). In the unlikely event that CHAR_MAX == INT_MAX,
(int)(unsigned char)s[pos] will have the same value as s[pos].
Therefore, if s[pos] is sufficiently close to INT_MIN, subtracting '0'
from it will have undefined behavior.
In the unlikely event that UCHAR_MAX > INT_MAX, s[pos] is promoted to an
unsigned int (6.3.1.1p2). Since '0' has the type 'int', and 'int' and
unsigned int' have the same integer conversion rank, the usual
arithmetic conversions specify that '0' is converted to unsigned int,
and the subtraction is carried out in that type. If s[pos] is less than
'0', then s[pos] - '0' will have a mathematical value that is negative,
so it will have to wrap around.