In the code below:
#include <stdio.h>
struct
{
int Member1 : 3;
int Member2 : 1;
}d2;
int main(){
d2.Member1 = 7;
printf("%d\n",d2.Member1);
return 0;
}
The result is -1
, why is it? What's the binary value of the d2
now?
In the code below:
#include <stdio.h>
struct
{
int Member1 : 3;
int Member2 : 1;
}d2;
int main(){
d2.Member1 = 7;
printf("%d\n",d2.Member1);
return 0;
}
The result is -1
, why is it? What's the binary value of the d2
now?
Because you did not specify if d2.Member1
is signed or unsigned, it is up to the compiler and apparently the one you are using chose to make it a signed field, and therefore has the range -4 to 3. 7 is out of range, so it overflows.
Make d2.Member1
an unsigned int
instead, and use %u
in your printf()
call instead of %d
. (Demo.)
You assign binary 111 to 3-bit value. Since you declared the field as signed, this means 3-bit long '-1'. When you request an integer value, it is left-padded with the leftmost bit to preserve the sign.
If you expect the output 7, declare your bit field as unsigned Member1: 3
. Expansion to full integer will pad the missing MSB with 0 rather than the leftmost bit.
To quote the C90 standard:
A bit-field shall have a type that is a qualified or unqualified version of one of
int
,unsigned int
, orsigned int
. Whether the high-order bit position of a (possibly qualified) “plain”int
bit-field is treated as a sign bit is implementation-defined. A bit-field is interpreted as an integral type consisting of the specified number of bits.
So it's -1
because you didn't explicitly specify it as unsigned and, in the C implementation you're using, the high-order bit position of a "plain" int
bit-field is treated as a sign bit. You have a 3-bit bit-field, all the bits of which are 1, so that's -1.
C language does not define whether an int
bit-field is signed or unsigned. The decision is left to implementation. For this reason, it is typically not a good idea to ever declare int
bit-fields. Use either explicitly signed int
or explicitly unsigned int
bit-fields, depending on what you need. (It is one area of C language where int
does not necessarily mean signed int
.)
In your case your 3-bit int
bit-field happened to be signed. The value range of such bit-field is [-4, 3]
, assuming 2's-complement representation. You attempted to assign 7
to it, causing overflow. What happens in case of signed integer overflow on assignment is implementation-defined. You ended up with -1
apparently.