I'm reading a Stroustrup's book "The C++ Programming Language 4th edition" and have three questions regarding overflowing assignments (particularily to signed/unsigned chars, as the book exemplifies). Firstly, according to standard 5/4 paragraph:
If during the evaluation of an expression, the result is not
mathematically defined or not in the range of representable values for
its type, the behavior is undefined.
(Except when a destination variable is unsigned - the result is clearly defined in such case). But does this definition also pertain to assignments?
Because in my opinion there are many contrary statements in the book, all in chapter 6. The first one corresponds to the aforementioned paragraph, however the following comments doesn't:
Variables of the three char
types can be freely assigned to each
other. However, assigning a too large value to a signed char
is still
undefined. For example:
void g(char c, signed char sc, unsigned char uc)
{
c = 255; //implementation-defined if plain chars are signed and have 8 bits
c = sc; //OK
c = uc; //implementation-defined if plain chars are signed and if uc's value is too large
sc = uc; //implementation-defined if uc's value is too large
uc = sc; //OK: conversion to unsigned
sc = c; //implementation-defined if plain chars are unsigned and if c's value is too large
uc = c; //OK: conversion to unsigned
}
First question: since assigning a too large value is UB, then why comments say it's implementation-defined?
Next we have the following example:
To be concrete, assume that a char
is 8 bits:
signed char sc = -160;
unsigned char uc = sc; //uc == 116 (because 256-160==116)
cout << uc; //print 't'
Second question: apart from the fact that the first assignment is supposedly UB, what formula exactly has the author used in order to come up with 116? In my test, uc
got the value of 96.
And the last quote:
An integer can be converted to another integer type. If the
destination is signed
, the value is unchanged if it can be
represented in the destination type; otherwise, the value is
implementation-defined:
signed char sc = 1023; //implementation-defined
Plausible results are 127 and -1.
Third question: again, apart from the fact that this contrary to what have been said earlier about UB, why possible results are 127 and -1? I guess it has something to do with one's and two's complement, but what are the precise formulas used?