Re: How to use bitfields?



cman wrote:
Who can explain to me what bitfields are and how to use them in
practice? I would need a fairly detailed explaination, I would be a
newbie to advanced C programming features.

Bitfields are not an "advanced" feature of C. In fact, there is not much difference with other integer types beside their bit size.

What are the advantages of using bitfields?

Memory usage, essentially, at the very lowest possible level. Note that we could always do without bitfields anyway (by using bitwise operators like & and |). It's just for readability that bitfields are used.

They are often used to provide an intuitive interface to an underlying IO register or low-level structure. This way, you use the same semantic to access values as any other type. Consider, as an example, a pixel definition in some 16 bits ARGB format:

#include <stdio.h>
#include <stdint.h> // C99 uint16_t

struct ARGB1555 {
union {
uint16_t value;
struct {
unsigned int blue : 5;
unsigned int green : 5;
unsigned int red : 5;
unsigned int alpha : 1;
} comp;
} u;
};

int main(void)
{
struct ARGB1555 pixel;
pixel.u.comp.red = 20;
pixel.u.comp.green = 22;
pixel.u.comp.blue = 7;
pixel.u.comp.alpha = 1;
printf( "red: %d, green: %d, blue: %d, alpha: %d\n",
pixel.u.comp.red,
pixel.u.comp.green,
pixel.u.comp.blue,
pixel.u.comp.alpha );

return 0;
}

This is far more readable than this uggly equivalent machine dependant crap:

int main(void)
{
struct ARGB1555 pixel;
pixel.u.value = (1 << 15) | (20 << 10) | (22 << 5) | 7;
printf( "red: %d, green: %d, blue: %d, alpha: %d\n",
(pixel.u.value >> 10) & 0x1f,
(pixel.u.value >> 5) & 0x1f,
pixel.u.value & 0x1f,
(pixel.u.value >> 15) & 0x1 );

return 0;
}

Of course, you may use constants for components instead of bare hardcoded values (so porting the code would just have to redefine them, like bitfields), but anyway this would still make the code harder to read and even a lot harder to write.

Also, think about integer operations... even the simplest would be a bargain without bitfields. Just consider:

pixel.u.comp.blue += 12;

Doing this simple operation without bitfields should be done with great care in complex and hard to read expressions. Most programmers would certainly introduce a temporary variable to handle it more easily, but still. By using bitfields, you make the code a lot more readable while the compiler takes care of all the masking and shifting bargain.



--
R.N.
.



Relevant Pages

  • Re: How to use bitfields?
    ... It's just for readability that bitfields are used. ... struct ARGB1555 { ... unsigned int green: 5; ... for the same target, ...
    (comp.lang.c)
  • Re: Variable declaration followed by colon?
    ... A couple of common examples where bitfields are used are device drivers, ... Here's the IP header struct that's used in every packet: ...   unsigned int version:4; ...
    (comp.lang.c)
  • Re: Variable declaration followed by colon?
    ... A couple of common examples where bitfields are used are device drivers, ... you're relying on bitfields every time you send an IP packet! ... Here's the IP header struct that's used in every packet: ... unsigned int version:4; ...
    (comp.lang.c)
  • Re: How to use bitfields?
    ... It's just for readability that bitfields are used. ... struct ARGB1555 { ... unsigned int green: 5; ... I don't use C because of its portability, but because it is the only language that allow me to do pseudo-assembly low-level code very tied to the hardware in such a way that I don't have to rewrite everything for each target. ...
    (comp.lang.c)
  • (Resend of 23/70 plus reply [PATCH 00/70] tty updates proposed for 2.6.27)
    ... So rework the entire API to pass the tty struct. ... const unsigned char *source, int count) ... unsigned int set, unsigned int clear) ...
    (Linux-Kernel)