Bit masks are where you specify the number of bits to use in a integral
member of a class or struct. C has more restrictions than C++ on
this. In particular, only "int", "signed int" or "unsigned int" can have bit
masks in C. Many C compilers ignore bit masks altogether.
First rule of bit masks: Don't. Don't unless you have a really bad
need to save a tiny amount of memory, and slowing down your code a lot isn't a
problem (the compiler will have to work around things as they are not properly
aligned). Bit masks are also inherently non-portable and differ on different
compilers on different machines. Some compilers will ignore them totally.
If you really want to go ahead with it, all you do is put a colon after the
member followed by the number of bits it should occupy. Here's an example:
struct TwelveHourTime
{
unsigned hour : 4; //4 bits (16), enough for 1-12
unsigned minute : 6; //6 bits (64), enough for 0-59
unsigned am : 1; //1 bit, on for am off for pm
};
// 0 1 2 3 4 5 6 7 8 9 A
// |_ _ _ _|_ _ _ _ _ _|_|
// hour minute am
You can use bit masks with a blank identifier to add some padding:
struct TwelveHourTime
{
unsigned hour : 4; //4 bits (16), enough for 1-12
unsigned minute : 6; //6 bits (64), enough for 0-59
unsigned : 5; //5 unused bits
unsigned am : 1; //1 bit, on for am off for pm
};
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
// |_ _ _ _|_ _ _ _ _ _|_ _ _ _ _|_|
// hour minute (unused) am
You can a blank identifier with bit mask of 0 to force the next element to
align to the boundary of the given type:
struct TwelveHourTime
{
unsigned hour : 4; //4 bits (16), enough for 1-12
char : 0; //push minute to the next byte boundary
unsigned minute : 6; //6 bits (64), enough for 0-59
unsigned am : 1; //1 bit, on for am off for pm
};
// 0 1 2 3 4 5 6 7 8 9 A B C D E
// |_ _ _ _|_ _ _ _|_ _ _ _ _ _|_|
// hour (unused) minute am
Again, bit masks are very non-portable and the exact layout depends on the
compiler and platform. The diagrams are a guide only.
No comments:
Post a Comment