Re: bitfields

From: Mark Devlin (markd@eskimo.com)
Date: 11/26/95


On Sun, 26 Nov 1995, Pink Floyd wrote:

> I was under the impression that you can do the following with a bitfield:
> Say you want to read in a status byte from a piece of hardware, but are only
> interested in, say, the 5th and 6th bytes.  You can:
> ...
> struct status_byte {
>   unsigned buf      :   4;  /* this will hold the first 4 bytes */
>   unsigned status_5 :   1;
>   unsigned status_6 :   1;
>   unsigned buf2     :   2;
> ...
> This will accurately allow you to get just the 5th and 6th bytes, or at least
> it should, otherwise bitfields wouldn't be nearly as useful! So I guess I'm
> not sure, will it?
> 

If you don't care about 'x' bits, you don't have to give them a tag (I
think that's the right term, been a while :-) ):
	unsigned : 5;
would work just fine, for example

However, as someone else pointed out, there's no guarantees with
bitfields.  You're safe as long as they're only used within the
program, ie not saved to disk.  BUT, I don't think there'd be any
problems if you only plan on using the data files on one machine.

Also, you can't just specify however many bits you want, the maximum
is the number of bits in an int. (could be mistaken, but I just tested
it with gcc 2.7.0 and it's correct).

Bitfields are a hassle for portability if you make assumptions about
how they're implemented.  With bitvectors, you know exactly what's
going where, and if you use the code that follows, you don't have do
worry about int sizes, either.

#include <limits.h>         /* for CHAR_BIT */

#define BITS2BYTES(x) (((x)/CHAR_BIT)-((((x)/CHAR_BIT)*CHAR_BIT)==(x))+1)
#define BITMASK(bit)        (1L << ((bit) % CHAR_BIT))
#define BITSLOT(bit)        ((bit) / CHAR_BIT)
#define BITSET(ary, bit)    ((ary)[BITSLOT(bit)] |= BITMASK(bit))
#define BITCLR(ary, bit)    ((ary)[BITSLOT(bit)] &= ~BITMASK(bit))
#define BITTST(ary, bit)    (((ary)[BITSLOT(bit)] & BITMASK(bit)) != 0)
#define BITTGL(ary, bit)    ((ary)[BITSLOT(bit)] ^= BITMASK(bit))

Use the BITS2BYTES macro when declaring a bitvector:
	unsigned char bits[BITS2BYTES(1000)];
Which will provide a large enough array of bytes to hold at least 1000
bits.  The last four macros are the ones to use for accessing the
individual bits, 'ary' is the bitvector ('bits' in the declaration
above), and 'bit' is the bit you want to manipulate.

No guarentees on anything above, it's fresh from the old noggin', and
will probably cause the destruction of Earth if you use it.  You were
warned. :-)
 
- Mark
markd@eskimo.com



This archive was generated by hypermail 2b30 : 12/07/00 PST