hari said:
Hi all,
Sorry to ask the same type of question again,My understanding is
1. whenever a unsigned number(short) is assigned to a signed number
(inetger type),its sign bit is not extended. (i.e when assigning FROM
UNSIGNED SMALLER DATA TYPE TO OTHER DATA TYPE WHIC HAS HIGHER SIZE).
The conversion preserves the value. Since the unsigned
value is non-negative, the converted signed value is also
non-negative.
Also, there is no question about "extending the sign bit"
of an unsigned integer, because an unsigned integer has no
sign bit at all.
But when I asssign a unsigned integer with neagtive value to signed or
unsigned number,sign bit is extended.
I'm not sure what you mean. No unsigned integer can ever
have a negative value, and no unsigned integer has a sign bit.
Is this is right, pleasegive me brief explanation if Im wrong? Sorry..
#include<stdio.h>
int main()
{
unsigned int y =255;
A conversion occurs in this initialization. The initializer
is an int with the value 255, and the thing being initialized is
an unsigned int. The int 255 is converted to unsigned int, giving
the value 255u, and that is the initial value of `y'.
A conversion occurs in this initialization. The initializer
is an int with the value -255, and the thing being initialized
is an unsigned short. The int -255 is converted to unsigned short,
but since the unsigned short cannot have a negative value this
conversion must produce some other value. By the rules of signed-
to-unsigned conversion, the new value is (short)(USHRT_MAX+1-255),
which on many machines will be (short)(65535+1-255) or (short)65281,
which can also be written as (short)0xFF01. (Larger values for
USHRT_MAX are possible, but seldom seen.)
No conversion occurs: Both the initializer and the variable
being initialized are int.
A conversion occurs in this initialization. The initializer
is an int with the value -255, and the thing being initialized is
an unsigned int. Since an unsigned int cannot have a negative
value, conversion alters the value, as above. This time the rules
produce UINT_MAX+1-255, typically 4294967295+1-255 or 4294967041u,
which can also be written as 0xFFFFFF01 (on some systems UINT_MAX
may be 65535, and you'll get 65281u==0xFF01; still other values are
possible but rare).
This is just a little bit problematic. On many machines the
range of int is wider than that of unsigned short, and all will
be well: gm will be assigned the value USHRT_MAX+1-255, which
is likely to be 65281. But on some machines int and short will
have the same number of bits, and USHRT_MAX > INT_MAX. On these,
it will turn out that the value in my is outside the range that
the int gm can express, and you'll get an implementation-defined
outcome (which might include raising a signal). Usually, the
implementation-defined outcome is to deliver a "wrapped around"
result, but this isn't absolutely guaranteed.
printf("\ny-> %x,\nmy-> %x,\n imy->%x,\n uy->%x,\n gm->
%x",y,my,imy,uy,gm);
Additional conversions occur here, and there's also some
undefined behavior (whose consequences are probably not serious,
but in principle anything can happen).
printf() is a "variadic" function, one that can accept
different argument lists in different calls. The first argument
is always the format string, but the remaining arguments can
be pretty much anything. These extra arguments are subject to
the "default argument promotions," so the argument values you
supply are sometimes converted to different types by the time
printf() actually receives them.
Your five extra arguments are of three types: y and uy
are unsigned int, imy and gm are (signed) int, and my is
an unsigned short. Arguments that are int or unsigned int
are not affected by the promotions, but the unsigned short
argument may be. If an int can hold all possible values of
an unsigned short, the unsigned short is converted to an
int; this is the commonest outcome. But on machines with
"narrow" ints, where USHRT_MAX > INT_MAX, the conversion is
to unsigned int instead. Either way the value is preserved,
but the type that printf() receives will in no case be an
unsigned short. The arguments received by printf() will be
two or three unsigned ints, and three or two signed ints.
The (probably harmless) undefined behavior arises from
using the "%x" conversion specifier, which requires a matching
argument of type unsigned int. As we've seen above, either
two or three of the arguments are signed int, not unsigned int,
so this is an error. What usually happens is that printf()
displays the value the argument would have had if its bits
were interpreted as an unsigned int, but this behavior is not
actually guaranteed and in principle anything could happen.