Presumably you mean "signed int to *unsigned* int". int is the same as
signed int in almost all situations.
Thanks Ben, Yes, I meant it, sorry for the typo.
Here are the declarations moved up to help read this in order:
| int i;
| unsigned int j = UINT_MAX;
| unsigned char c = UCHAR_MAX;
'c + 1' is already an int so it is not converted. 'c' is converted to
int before the addition. This is part of what C calls the "usual
arithmetic conversions". So, 'c' gets converted to int and one is added
to that. The result is put in 'i' with no further conversion. When
UCHAR_MAX is 255, 'i' gets the value 256.
OK.
By the way, all of this discussion is about the normal situation where
UCHAR_MAX is <= INT_MAX. On some peculiar systems, the rules can
produce different results.
No, it's fine. In this case, when c is UCHAR_MAX the result in 'i' is
0. I could tell you why, but you might learn more by trying to work out
why for yourself. Let me know (well, let the group know) if you are
unsure.
OK, let me try.
++c is equal to c = c + 1, and 'c' is converted to int. So when
UCHAR_MAX is 255, 'c + 1' is 256, which is int. Then int value of 256
is assigned to 'c',
which is unsigned char.
When I look into '6.3.1.3 Signed and unsigned integers', it says that
'if a value
with integer type is converted to another integer type and the value
cannot be
represented by the new type, and if the new type is unsigned value,
the value is
converted by repeatedly adding or subtracting one more than the
maximum value
that can be represented in the new type until the value is in the
range of the new type.'
I think above sentence is not clear enough, but I found following way
to convert in other place(which is the book written in non-English).
If there is clearer description of converston rules in C specification
document, please tell me.
So 256 ,which is signed int cannot be represented by the unsigned
char, therefore 256 % (1 + UCHAR_MAX) = 0 in this case.
Other than that, what I found for signed/unsigned integer conversion
rules are followings:
(1)From signed X to signed Y
X <= Y x
X > Y if x can be represented by signed Y, then x
if x cannot be represented by signed Y, then
undefined
(2)From unsigned X to signed Y
X < Y x
X >= Y if x can be represented by signed Y, then x
if x cannot be represented by signed Y, then
undefined
(3)From signed X to unsigned Y
X < Y when value of X >= 0, then x
when value of X < 0, then (signed Y)x + (1 +
Y_MAX)
X == Y when value of x >= 0, then x
when value of X < 0, then x + (1 + Y_MAX)
X > Y when value of x >= 0, then x % (1 + Y_MAX)
when value of X < 0, then (1 + Y_MAX) - (-x %
(1 + Y_MAX))
(4)From unsigned X to unsigned Y
X <= Y x
X > Y x % (1 + Y_MAX)
If above from (1) to (4) are correct, there are 2 cases that can be
undefined.
One is the case like following case:
int i = INT_MAX;
char c;
c = i;
The Other is the case like following:
unsigned int i = UINT_MAX;
char c;
c = i;
No, this too is fine (in the exact case you are asking about). First
you need to know that j is not converted to an int but, instead, 1 is
converted to unsigned int. Unsigned arithmetic does not overflow, it
"wraps round" so 'j + 1' is 0 when 'j' is UINT_MAX and this unsigned int
result can be represented in 'i' so the conversion to int and subsequent
assignment is valid.
I see, I did not know that UINT_MAX + 1 becomes legally 0.
Had 'j' been UINT_MAX-1 to start with, the conversion of 'j + 1' to int
would have been either implementation defined or an implementation
defined signal would be raised.
Again, that's fine.
OK, then j + 1 becomes 0, so j becomes 0 and assigned to i.
Thank you