5
   struct stats
   {
       char top         : 1; 
       char bottom      : 1;
       char side        : 2;
   } MyStat;  

I have seen this format with integers but how does the above char bit field work and what does it represent?

Thank You.

T.T.T.
  • 33,367
  • 47
  • 130
  • 168

3 Answers3

7

Char bit fields work in the same way as int, just the base type is 8-bit wide, not 32-bit. So you'd get a struct stats, which has the size of 1 byte, and 3 member variables, occupying a total of 4 bits.

  • 1
    @Tommy: you should really be careful with `char` here because this is not portable and they have the ambiguity that they may be signed or unsigned types. If you may, avoid this and use `unsigned` or `_Bool`. Two bits of an `unsigned` need exactly as much space as two bits of a `char` ;-) – Jens Gustedt Oct 19 '10 at 18:42
  • 1
    Not to mention you should avoid bitfields to begin with. – R.. GitHub STOP HELPING ICE Oct 19 '10 at 21:20
5

Bitfields should be declared with type signed int, unsigned int, or bool from <stdbool.h>. Other types may or may not be legal (depending on the platform), but be careful about the signedness — plain int may be taken to be unsigned for a bitfield.

That said, it may be a hint to the compiler that the alignment of the struct should be 1 and not sizeof(int). And the compiler is allowed to accept char and assign it such meaning.

According to C99 6.7.2.1/9,

A bit-field is interpreted as a signed or unsigned integer type consisting of the specified number of bits. If the value 0 or 1 is stored into a nonzero-width bit-field of type _Bool, the value of the bit-field shall compare equal to the value stored.

and a footnote:

As specified in 6.7.2 above, if the actual type specifier used is int or a typedef-name defined as int, then it is implementation-defined whether the bit-field is signed or unsigned.

Potatoswatter
  • 134,909
  • 25
  • 265
  • 421
  • 3
    C99 explicitly says in 6.7.2.1/4 "_Bool, signed int, unsigned int, or some other implementation-defined type". Presumably the implementation is free to define whether the bit-field container object is really as small as a single `char` as it appears it could be in this case. – RBerteig Oct 19 '10 at 18:34
  • 1
    @RBerteig: Did I say something to contradict that? – Potatoswatter Oct 19 '10 at 18:46
  • 1
    Sorry, I apparently read "Other types may or may not be legal..." as not really saying "implementation defined". (My only excuse is immersion in standardese with insufficient caffeine.) I can't find any clear answer from the standard about what `sizeof()` should say in this case, however. – RBerteig Oct 19 '10 at 18:52
  • 1
    @RBerteig: I (think I) clarified it a bit. I'm pretty sure `sizeof` is implementation-defined when there's a bitfield, and I seem to recall doing an experiment with GCC where the size of the declared type did make a difference. – Potatoswatter Oct 19 '10 at 18:55
  • 1
    the embedded systems cross compilers I've used generally have taken the declared type holding the bit fields as an indication of what kind of memory access to do. So a bitfield in a `char` would use byte-acess, a `short` would use 16-bit accesses, and a `long` would use 32-bit accesses. This matters a great deal in some architectures where a 16-bit wide device may not be legally accessed 8 bits at a time without doing two reads which could loose some information in registers that are cleared when read. That is **very** implementation defined, and non-portable, though. – RBerteig Oct 24 '10 at 21:21
2

it just defines the size of the variable that you will use.

char
int

This is not supported by the standard (typical use is unsigned int), but it's a nice attempt :)

re: your query, it's an attempt by the implementer to use less memory for their bitfields (char as opposed to unsigned int)

Additionally, from Atmel, we get:

in the C Standard, only “unsigned (int)” and “int” are acceptable datatypes for a bitfield member. Some compilers allow “unsigned char” ........

KevinDTimm
  • 14,226
  • 3
  • 42
  • 60
  • what are the possible values for a 1 bit char? – T.T.T. Oct 19 '10 at 17:53
  • 1
    it's not a one bit char, it's one bit inside of a char – KevinDTimm Oct 19 '10 at 17:59
  • 2
    char is one byte in size, so it takes values -128 to 127 (signed) or 0 to 255 (unsigned). If you want to use it as a bit field, you need to use masks and the bitwise operators | & ^ ~ << and >> – Tristan Oct 19 '10 at 18:02
  • 1
    @Tristan - not really. Most compilers (regardless of what the Standard says) allow bit operations like the OP details on a char. These operations CAN use the bitwise operators but don't HAVE to use them. For example, bitfields are a great way to define which pieces of data are sent in a stream, in which case you would turn them on and off as appropriate – KevinDTimm Oct 19 '10 at 18:08
  • 1
    from C++ (2003 version) standard: It is implementation-defined whether a plain (neither explicitly signed nor unsigned) char, short, int or long bit-field is signed or unsigned. >>>> I think it's reasonable to think char is supported –  Oct 19 '10 at 18:13
  • 2
    @buratinas - unfortunately, the OP refers to C and C++. The good news is we're both right ;) – KevinDTimm Oct 19 '10 at 18:26
  • 1
    C99 explicitly says in 6.7.2.1/4 "_Bool, signed int, unsigned int, or some other implementation-defined type". So it is allowed, but it is implementation defined and so not as portable. Of course, not a lot about bit-fields is portable. – RBerteig Oct 19 '10 at 18:35
  • 1
    They're portable for the use I defined earlier, but always a great danger when dealing with machine dependent stuff. Of course, anything machine independent is 'great danger', which is why it's fun. – KevinDTimm Oct 19 '10 at 19:08