Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Alternative approach to bitfields

Reply
Thread Tools

Alternative approach to bitfields

 
 
W Karas
Guest
Posts: n/a
 
      07-23-2012
The idea is to define the bitfields using a "map" structure of arrays of char, with each char corresponding to a bit in an unsigned integer. Here is some example code:

/* Notes
** 1. parameters to these macros may appear multiple times in the
** macro definition, so do not use expresions with side-effects as
** actual parameters.
** 2. If parameters to these macros are not in the correct range,
** results are undetermined.
*/

/* Get the value of the bitfield with the given WIDTH at the offset OFS in
** the rvalue RV of unsigned integer type UT.
*/
#define BF_GET_N(UT, RV, WIDTH, OFS) \
(((RV) >> (OFS)) & BF_H_MW(UT, WIDTH))

/* Logically OR the value VAL into lvalue LV after left-bit-shifting it
** by OFS bits.
*/
#define BF_OR_N(LV, OFS, VAL) \
{ BF_H_OR_N_EXPR(LV, OFS, VAL); }

/* Set the value VAL in the bitfield with the given WIDTH at the offset OFS
** in the lvalue LV of unsigned integer type UT.
*/
#define BF_SET_N(UT, LV, WIDTH, OFS, VAL) \
{ ((WIDTH) >= (sizeof(UT) * CHAR_BIT)) ? \
(*&(LV) = (VAL)) : \
(*&(LV) &= ~(BF_H_MW(UT, WIDTH) << (OFS)), \
BF_H_OR_N_EXPR(LV, OFS, VAL)); }

/* A "bitfield map structure" is recursively defined as a C/POD struct or
** union where each member is an array of char or a bitfield map structure.
** Each array of char represents a bitfield. The sizeof the array gives
** the width of the bitfield. The byte offset of the array from the
** start of the top-level structure gives the offset of the bitfield.
*/

/* Get the value of the bitfield in the rvalue RV of unsigned integer type
** UT corresponding to the field FLD in bitfield map structure MSTRU.
*/
#define BF_GET(UT, RV, MSTRU, FLD) \
BF_GET_N(UT, RV, BF_H_WIDTH(MSTRU, FLD), BF_H_OFS(MSTRU, FLD))

/* Logically OR the value VAL into value of the bitfield in the rvalue RV of
** unsigned integer type ** UT corresponding to the field FLD in bitfield map
** structure MSTRU.
*/
#define BF_OR(LV, MSTRU, FLD, VAL) \
BF_OR_N(LV, BF_H_OFS(MSTRU, FLD), VAL)

/* Set the value VAL in the bitfield in the rvalue RV of unsigned integer
** type UT corresponding to the field FLD in bitfield map structure MSTRU.
*/
#define BF_SET(UT, LV, MSTRU, FLD, VAL) \
BF_SET_N(UT, LV, BF_H_WIDTH(MSTRU, FLD), BF_H_OFS(MSTRU, FLD), VAL)

/* --------------------------------------------------------------------- */

/* "Private" macros, not meant for direct use. */

#include <limits.h>

/* Mask of WIDTH and type UT.
*/
#define BF_H_MW(UT, WIDTH) \
((UT) (((WIDTH) >= (sizeof(UT) * CHAR_BIT)) ? \
(~ (UT) 0) : ((((UT) 1) << (WIDTH)) - 1)))

/* BF_OR_N as expression not statement.
*/
#define BF_H_OR_N_EXPR(LV, OFS, VAL) \
(*&(LV) |= ((VAL) << (OFS)))

/* Returns offset of bitfield corresponding to char array FLD in bitfield
** map structure MSTRU.
*/
#define BF_H_WIDTH(MSTRU, FLD) \
(sizeof(((MSTRU *) 0x100)->FLD))

/* Returns width of bitfield corresponding to char array FLD in bitfield
** map structure MSTRU.
*/
#define BF_H_OFS(MSTRU, FLD) \
((((MSTRU *) 0x100)->FLD) - ((char *) 0x100))

/* These macros lay out the bit fields with higher offsets at higher
** significance, but the reverse is also possible.
*/

/* --------------------------------------------------------------------- */

/* Test code */

typedef struct
{
union
{
/* Array of 4 5-bit-wide bitfields (cool eh?). */
char fa[4][5];

struct
{
char f1[6], f2[14];
}
sm;
}
u;

char f3[12];
}
Map_bf;

#include <stdio.h>
#include <stdlib.h>

void bail(void)
{
printf("FAIL\n");
exit(1);
}

int main(void)
{
unsigned va[4], v1, v2, v3, i, v;

v = 0xabcd1234;

for (i = 0; i < 4; ++i)
va[i] = BF_GET(unsigned, v, Map_bf, u.fa[i]);
v3 = BF_GET(unsigned, v, Map_bf, f3);

if (v != 0xabcd1234)
bail();

v = 0x1234abcd;

for (i = 0; i < 4; ++i)
BF_SET(unsigned, v, Map_bf, u.fa[i], va[i])
BF_SET(unsigned, v, Map_bf, f3, v3);

if (v != 0xabcd1234)
bail();

v = 0xabcd1234;

v1 = BF_GET(unsigned, v, Map_bf, u.sm.f1);
v2 = BF_GET(unsigned, v, Map_bf, u.sm.f2);
v3 = BF_GET(unsigned, v, Map_bf, f3);

if (v != 0xabcd1234)
bail();

v = 0x1234abcd;

BF_SET(unsigned, v, Map_bf, u.sm.f1, v1)
BF_SET(unsigned, v, Map_bf, u.sm.f2, v2)
BF_SET(unsigned, v, Map_bf, f3, v3)

if (v != 0xabcd1234)
bail();

v = 0xabcd1234;

for (i = 0; i < 4; ++i)
va[i] = BF_GET(unsigned, v, Map_bf, u.fa[i]);
v3 = BF_GET(unsigned, v, Map_bf, f3);

v = 0;

for (i = 0; i < 4; ++i)
BF_OR(v, Map_bf, u.fa[i], va[i])
BF_OR(v, Map_bf, f3, v3)

if (v != 0xabcd1234)
bail();

v = 0xabcd1234;

v1 = BF_GET(unsigned, v, Map_bf, u.sm.f1);
v2 = BF_GET(unsigned, v, Map_bf, u.sm.f2);
v3 = BF_GET(unsigned, v, Map_bf, f3);

v = 0;

BF_OR(v, Map_bf, u.sm.f1, v1)
BF_OR(v, Map_bf, u.sm.f2, v2)
BF_OR(v, Map_bf, f3, v3)

if (v != 0xabcd1234)
bail();

printf("SUCCESS\n");

return(0);
}
 
Reply With Quote
 
 
 
 
Ike Naar
Guest
Posts: n/a
 
      07-23-2012
On 2012-07-23, W Karas <(E-Mail Removed)> wrote:
> /* Returns offset of bitfield corresponding to char array FLD in bitfield
> ** map structure MSTRU.
> */
> #define BF_H_WIDTH(MSTRU, FLD) \
> (sizeof(((MSTRU *) 0x100)->FLD))
>
> /* Returns width of bitfield corresponding to char array FLD in bitfield
> ** map structure MSTRU.
> */
> #define BF_H_OFS(MSTRU, FLD) \
> ((((MSTRU *) 0x100)->FLD) - ((char *) 0x100))


Were the comments for these macros swapped?
 
Reply With Quote
 
 
 
 
wkaras@yahoo.com
Guest
Posts: n/a
 
      07-23-2012


On Monday, July 23, 2012 2:15:13 AM UTC-4, Ike Naar wrote:
> On 2012-07-23, W Karas wrote:
> &gt; /* Returns offset of bitfield corresponding to char array FLD in bitfield
> &gt; ** map structure MSTRU.
> &gt; */
> &gt; #define BF_H_WIDTH(MSTRU, FLD) \
> &gt; (sizeof(((MSTRU *) 0x100)-&gt;FLD))
> &gt;
> &gt; /* Returns width of bitfield corresponding to char array FLD in bitfield
> &gt; ** map structure MSTRU.
> &gt; */
> &gt; #define BF_H_OFS(MSTRU, FLD) \
> &gt; ((((MSTRU *) 0x100)-&gt;FLD) - ((char *) 0x100))
>
> Were the comments for these macros swapped?


oops
 
Reply With Quote
 
Jorgen Grahn
Guest
Posts: n/a
 
      07-24-2012
On Mon, 2012-07-23, W Karas wrote:
> The idea is to define the bitfields using a "map" structure of

....

Please don't multipost. This (or a very similar) posting also showed
up in comp.lang.c++. Crosspost if you feel you must.

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Alternative approach to bitfields W Karas C++ 9 07-24-2012 06:19 PM
Give me some alternative approach for Jakartha POI PLzzzzzzzzzzzz Swapna14 Software 0 11-16-2006 06:04 AM
where are unions and bitfields particularly used ? rohit C Programming 23 06-10-2004 03:01 AM
About very long Bit-numbers (bitfields?) Juha Kettunen C++ 9 04-10-2004 01:10 AM
About bitfields Régis Troadec C Programming 8 02-17-2004 05:59 PM



Advertisments