Gio said:
Code:
short i, j;
i = -32768;
j = -i;
printf("%d", j);
As some of you may have guessed by my previous post (about books), I'm
trying to learn C. Well, a friend of mine (who is a programmer) asked me
(who is not a programmer) what the output of this would be, and why.
Let's start off by assuming a simpler case, where i is -1, so j takes the
value 1. Since printf is a variadic function, "the default argument
promotions are performed on trailing arguments" (as the Standard says), so
the short int value of 1 is promoted to an int, which matches %d just
fine. So the problem (and yes, there may be one) is not with the %d.
Okay, so i = -32768, and that's a problem right there, because it's outside
the minimum range for short int, which is -32767 to +32767.
Implementations are free to provide wider ranges, but are not forced to. I
*guess* that your implementation actually supports -32768 to +32767. If
I'm right, then what's happening is that the program is trying to assign
-(-32768), which is +32768, into an object that can't support a value that
high. The result is undefined, and the Standard doesn't say anything at
all about what will happen. So whatever gets printed, count yourself lucky
that you probably didn't catch bubonic plague from this code.
But why -32768?
Okay, bearing in mind that the result is undefined so there doesn't even
have to *be* a reason, let's try to see if we can find one anyway.
Let's reduce the problem to four bits (a *really* short int).
You're doing this:
reallyshort i, j;
i = -8; /* bit pattern 1000, two's complement */
j = -i;
C promotes -8 to an int, and then does a unary minus on it, giving 8.
Assuming 16-bit ints (and the same argument applies to larger ints), this
has a bit pattern of 0000000000001000. If we're going to load this value
into j (which has only four bits), something has to give, and it's the
high bits that go, so j gets the value 1000, which is -8!
Using four bits per reallyshort saved me some typing and counting, but
precisely the same argument applies to 16-bit shorts, the only difference
being that a lot more 0s and 1s are involved.