Possible Duplicate:
Unsigned long with negative value
Assigning negative numbers to an unsigned int?
#include<stdio.h>
int main()
{
struct a
{
unsigned int i:3;
int c:3;
}s;
s.i=5;
s.c=5;
printf("s.i=%d\n",s.i);
printf("s.c=%u\n",s.c);
unsigned int x = -1;
printf(" x = %d", x);
return 0;
}
This outputs:
s.i=5
s.c=4294967293
x=-1
I am not clear about the output of “x” and “s.c”(s.c can store number of 3 bits only but in the output it is giving very large value).”x” is declared as unsigned so the bits stored in x are 1111111……. and the output of x should be a large value instead of -1. 1st printf() statement is giving the result as expected
I am using devc++ compiler.
It seems there are two things going on that need to be understood:
printf()conversion specifiersAnd two more things that help make sense of your output:
First,
printf()is a variadic function. It doesn’t know what the types of its arguments are (other than the format string), so you have to use conversion specifiers to tell it how to interpret the arguments. These arguments are subject to the "default argument promotions" such that your 3-bit bit fields are being promoted toints.You are using conversions specifiers (
%d,%u, and%d) that do not match the signedness of your data, so you will get undefined behavior that depends on how your data is actually represented in memory.Second, the C11 standard states:
(As far as I can tell, the details relevant here have been true at least since C89.)
This tells us a couple things about your code:
When you assign
-1to anunsigned int,UINT_MAX + 1is added to it, givingUINT_MAX, or4294967295for 32-bit integers.When you try to assign
5to a 3-bit signed bit field, the result is implementation-defined.So you’ve got both undefined and implementation-defined behavior, but we can still try to make sense of your output, just for fun. I’m assuming 32-bit integers and two’s complement representation.
Your system represents the
4294967295stored inxas11111111 11111111 11111111 11111111. When you toldprintf()that the argument you were passing it was signed, those same bits are interpreted as-1, which is the output you got.For
s.c, the implementation-defined behaviour you seem to have gotten is straightforward:the three bits
101representing5got stored as-is. That means that with the correct conversion specifier,printf()should shows.cas-3.Here are the values you’ve assigned:
The 3-bit values are promoted to 32-bit by left-padding with
0for the unsigned value and repeating the sign for the signed value:Which, when interpreted as signed, unsigned, and signed integers gives:
The
x=-1suggests to me that you are in fact using a two’s complement representation (which was a pretty safe bet, anyway), and the output fors.csuggests that yourints are 32 bits wide.