Q: C union bitfields casting I don't understand what happens when casting a bitfield.
Let's say we have this union and an example:
union {
  unsigned char data;
  int d : 3;
  unsigned char m : 3;
}x;

int main() {
  x.data = 182;
  // 182 (binary) -> 1 0 1 1 0 1 1 0
  printf("sizeof(x) = %lu\n", sizeof(x));
  printf("x.data = %d\n", x.data);
  printf("x.d = %d\n", x.d);
  printf("x.m = %d\n", x.m);
  printf("(unsigned char)x.d = %d\n", (unsigned char)x.d);
  printf("(signed char)x.d = %d\n", (signed char)x.d);
  printf("(signed char)x.m = %d\n", (signed char)x.m);
  printf("(unsigned char)x.m = %d\n", (unsigned char)x.m);
  return 0;
}

This is the output:
/*
sizeof(x) = 4
x.data = 182
x.d = -2
x.m = 6
(unsigned char)x.d = 254 //?
(signed char)x.d = -2    //?
(signed char)x.m = 6     //?
(unsigned char)x.m = 6   //?
*/

Now, I understand x.data, x.d, and x.m output, but what i don't understand is the result we get when casting.
What does happen in memory when casting? Why do we get these results:


*

*(unsigned char)x.d = 254

*(signed char)x.d = -2

*(signed char)x.m = 6

*(unsigned char)x.m = 6


EDIT:
What I do not understand is how is this handled in memory, and which parts are read when casting. I put 182 in x.data which in binary is 10110110. x.data, x.m and x.d give expected results to me, but why does for example (unsigned char)x.d return 254? Why doesn't it return 182 since x.data and x.d are in the same memory location and i casted x.d to be unsigned char which is same type as x.data is. 

A: The behaviour on setting a union via one member and reading back a different union member is undefined in C.
It's therefore pointless trying to analyse the behaviour in this specific case.
You ought to rebuild using a solution based around a memcpy: at least then the output will be analysable.
Also, note that %zu is an appropriate format specifier for a sizeof value: currently the printf behaviour is also undefined due to your using %lu.

A: x.d and x.m show no change by casting, which is to be expected. x.d has the same bit pattern in either case but is interpreted as -2 when it is considered signed, and 254 when those same bits are interpreted as unsigned.
The fact that these variables are grouped in a union will save space if you read and write one variable within the union, but is undefined behavior when you write one variable and read another.
