I want to know how comparison b/w unsigned and signed quantity is done
i.e. how the conversions takes place..
Before you can perform any kind of mathematical or bitwise operation
on an integer expression, the integer expression must undergo "integer
promotion". If the type of the expression is "int" or bigger, then no
integer promotion takes place. If the type of the expression is "int"
or smaller, then the expression gets promoted to either "signed int"
or "unsigned int".
Smaller than int: char, short
Bigger than or equal to int: int, long, long long
(The last one "long long" was introduced with the C Standard of 1999)
So let's say we have two objects as follows:
short unsigned i = 5;
long j = 15;
(If you don't specify the signedness, then the default is "signed".)
And let's say we have an expression as follows:
i + j
The first thing we need to do is promote both operands. "i" will get
promoted to either "signed int" or "unsigned int" depending on whether
USHRT_MAX is greater than INT_MAX.
if (USHRT_MAX > INT_MAX) it becomes signed int;
else it becomes unsigned int;
(It wants to become signed if possible)
On most systems, it'll become "signed int", but let's go against the
grain with our example and pretend it promotes to "unsigned int".
Because "j" is bigger than int, we don't do anything to it. So the
types we have so far are:
(unsigned int) + (signed long)
Next thing we have to do is make them the same size, and we do this by
making the smaller one bigger. Therefore, the "int" has to become
"long". If UINT_MAX is bigger than LONG_MAX, the "int" will become
"unsigned long", otherwise it will become "signed long". (Again, it
wants to become signed if possible). In our example, let's pretend
that it becomes "unsigned long". So our types so far are:
(unsigned long) + (signed long)
Last thing we do is match the signedness, and "unsigned" always takes
precedence, so the "signed long" becomes an "unsigned long" as
follows:
(unsigned long) + (unsigned long)
Now that the operands are of the same type, the operation can be
carried out.
So to summarise all that:
1) Promote both the operands.
2) Match the sizes. (Make the new smaller size "signed" if the range
is sufficient, otherwise make it "unsigned").
3) Match the signedness. (Unsigned takes precedence).
Hopefully I haven't made a mistake there but I'm not infallible so
wait a minute or two to see if anyone points out a mistake.
Is following program behavior undefined...
#include<stdio.h>
#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
This is 7.
int array[] = {23,34,12,17,204,99,16};
int main()
{
int d;
for(d=-1;d <= (TOTAL_ELEMENTS-2);d++)
printf("%d\n",array[d+1]);
To make this easier to read, I'm going to add 1 to d, and remove it
from d in the body of the loop:
for (d = 0; d <= (TOTAL_ELEMENTS-1); d++)
printf("%d\n",array[d]);
Seems fine to me.