Search code examples
cbit-manipulationavr-gcc

assign integer to C bitfield


Is the result well defined if an integer is assigned to a struct with bitfield?

#include <stdio.h>
#include <stdint.h>

struct my_struct
{
  uint8_t a_byte;
  float a_float;
  uint8_t baz:1;
  uint8_t boo:1;
} __attribute__((__packed__));

int main ()
{
  struct my_struct foo;
  foo.a_byte = 5;
  foo.a_float = 3.14159;

  foo.boo = 0;
  foo.baz = 3;   /* this one */

  printf ("a_byte       = %i\n", foo.a_byte);
  printf ("a_float      = %f\n", foo.a_float);
  printf ("baz          = %i\n", foo.baz);
  printf ("boo          = %i\n", foo.boo);

  return 0;
}

compiled with gcc -Wall -Wextra main.c, gcc warns with

main.c:19:13: warning: large integer implicitly truncated to unsigned type 
[-Woverflow]
   foo.baz = 3;

output is:

a_byte       = 5
a_float      = 3.141590
baz          = 1
boo          = 0

So in my tests only bit0 is assigned to the actual bitfield, (assigning 4 would result in 0).

avr-gcc (the final target is Atmel AVR) doesn't even warn but is this behaviour defined?


Solution

  • The behaviour is defined when you store into an unsigned bit field (only the given number of bits are stored). The behaviour is defined if a signed int fits into the bit field, otherwise the behaviour is implementation defined.

    Obviously you can't expect more than one bit to be stored if you declare a bit field of width 1.