#include <stdio.h>
struct test{
unsigned int a:3;
};
int main (int argc, char *argv[])
{
struct test b;
b.a = -7; // implicit truncation to 1
return 0;
}
-7 is a four bit number represented as 1111. Now my bitfield takes only 3 bits and has the unsigned qualifier. As per my knowledge unsigned 3 bit integers range from 0-7. Following this assumption, I first tried -7 = 1111 = 15. And that wraps around to +7. I even considered the possibility that the MSB was ignored for some reason but still no answer. The ONLY way I could get this answer was when i took the 2's complement of 1111 which is equal to +1(which is what the compiler also says). But I have no clue as to why this worked.
Here is what the C11 standard says, 6.3.1.3 Signed and unsigned integers paragraph 3:
The maximum of
ais 7, so the value7+1=8is added or subtracted till it is in the range.-7+8=1=>1is stored.-7in 2 complement is(~7)+1which is(~0b111)+0b1 = 0b11111000+0b1 = 0b111111001Store that in 3 bit and you get the last 3 bit of:0b001=1.0b1111in a 4 bit signed number as 2 complement would be-1. Applying the 2 complement to it:(~1)+1 = (~0b1)+0b1 = 0b1110+0b1 = 0b1111 = -1.You are correct that
0b1111in a 4 bit signed number as signed magnitude would be 7, but nobody uses signed magnitude anymore, AFAIK it gets removed from C23 and only 2 complement will be allowed. And even on a signed magnitude system, the result will still be 1 because the the C standard requires it (as by the above mentioned paragraph)