INF: Initializing Bitfields as Integers in C

ID Number: Q60252

4.x 5.00 5.10 6.00 6.00a 6.00ax 7.00 | 5.10 6.00 6.00a

MS-DOS | OS/2

Summary:

In Microsoft C versions 5.1, 6.0, 6.0a, 6.0ax, and 7.0 initializing

the values of an entire bitfield structure as an integer can be done

in several ways:

- Declare the bitfield structure as part of a union with an integer.

(This is the preferred method).

- Use an integer pointer by setting the pointer to the address of the

structure and then changing what the pointer points to.

- Enforce the bitfield type constraints to get a copy of the bitfield

into an integer variable.

For examples of these three methods, see below.

More Information:

In Microsoft C, bitfields are stored in word-sized blocks with the

least significant bit representing the first bit of the bitfield. For

example, the bitfields in bitstruct, defined below in the example, are

stored as follows:

< p4 > < p3 > < p2> <p1>

|?|?|?|?|?|?|?|?|?|?|?|?|?|?|?|?|

Assigning the integer 0x4c to this structure results in the following

bit pattern:

|0|0|0|0|0|0|0|0|0|1|0|0|1|1|0|0|

The bitfields are given the following respective values:

p1=0 p2=3 p3=2 p4=0

If the number of bits needed for a bitfield structure exceeds 16,

words will be added as needed to provide room for the structure with

no single bitfield crossing a word boundary.

Note: There is no "standard" for storing bitfields; therefore, any

program that depends on them being stored in this manner, low to high,

will not be portable.

Sample Code

-----------

struct strtype

{

unsigned p1:2;

unsigned p2:3;

unsigned p3:5;

unsigned p4:5;

} bitstruct;

union untype

{

struct strtype un_bitstruct;

unsigned bit_integer;

} bitunion;

unsigned *intptr;

unsigned intgr;

void main(void)

{

/* Using the bitfield structure only */

/* Set the pointer to address of bitfield */

intptr=(unsigned *)&bitstruct;

/* Change the bitfield */

*intptr=0x4c;

/* Get the new value */

intgr=*(unsigned *)&bitstruct;

/* Using an union makes this much easier (syntactically) */

/* Set the pointer */

intptr=&bitunion.bit_integer;

/* Change the bitfield */

bitunion.bit_integer=0x4c;

/* Get the new value */

intgr=bitunion.bit_integer;

}

Note: If you are using C 6.0 or later or QuickC 2.5 or later, you

could use the anonymous union construct that these compilers support.

In that case, the code would change to:

struct strtype

{

unsigned p1:2;

unsigned p2:3;

unsigned p3:5;

unsigned p4:5;

} bitstruct;

union untype

{

struct strtype un_bitstruct;

unsigned bit_integer;

}; // Look ma! No name..

unsigned *intptr;

unsigned intgr;

void main(void)

{

/* Using the bitfield structure only */

/* Set the pointer to address of bitfield */

intptr=(unsigned *)&bitstruct;

/* Change the bitfield */

*intptr=0x4c;

/* Get the new value */

intgr=*(unsigned *)&bitstruct;

/* Using an union makes this much easier (syntactically) */

/* Set the pointer */

intptr=&bit_integer; // See here...

/* Change the bitfield */

bit_integer=0x4c; // And here...

/* Get the new value */

intgr=bit_integer; // And here... (Much easier, huh?)

}

Additional reference words: 5.10 6.00 6.00a 6.00ax 7.00 C++