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++