Author |
Message |
Spehro Pefhan #1 / 4
|
 Bitfields vs. masking
The objective is to have some status bits that can be accessed either as a group (say, to set them all to a known state) or individually. I can see two obvious ways to do this in C: a) Use macros like those in the faq, eg. /* BITSET and BITMASK are defined already */ enum {bluestatus, redstatus}; unsigned char stat=0; BITSET(stat, bluestatus); if (0 != BITMASK(stat, redstatus)) { /* do something */}; b) union { unsigned char wchar; struct { /* bit order in a bit field is implementation dependent */ unsigned bluestatus: 1; unsigned redstatus: 1; } bits; } stat; stat.wchar = 0; /* this is portable */ stat.wchar = 1; /* clear redstatus, set bluestatus..this isn't */ stat.bits.bluestatus = 1; if (0 != stat.bits.redstatus) {/* do something */}; Which is better, and why? b) seems much more readable, but has possible portability issues, as noted. Is there some (glaringly obvious(?)) better way of doing it? Best regards, Spehro Pefhany -- "it's the network..." "The Journey is the reward"
Embedded software/hardware/analog Info for designers: http://www.*-*-*.com/ 9-11 United we Stand
|
Wed, 09 Feb 2005 18:00:37 GMT |
|
 |
Chris Tore #2 / 4
|
 Bitfields vs. masking
Quote:
>The objective is to have some status bits that can be accessed either as a >group (say, to set them all to a known state) or individually. >I can see two obvious ways to do this ... [(a) &/| ops; (b) bitfields
unioned with whole-word integers] Quote: >Which is better, and why? b) seems much more readable, but has possible >portability issues, as noted.
There is a rule of thumb one can use in programming that says: "as long as two different methods both work, use whichever one is more readable." The bitfield method is indeed generally more readable. It does also have portability issues. If you are *absolutely certain* that those portability issues are not a problem, I would say: go ahead and use method (b). In my experience, however, software that was never supposed to be ported, almost always is; and suddenly that portability issue that you thought was safe to ignore, is not. Your experience may differ, and/or you may decide that the (small?) risk of a future maintenance nightmare is outweighed by the advantage of today's increased code-readability. Personally, I would go with explicit "&" and "|" operations, because I have been burned too often by the bitfield method. :-) -- In-Real-Life: Chris Torek, Wind River Systems (BSD engineering)
|
Thu, 10 Feb 2005 00:45:53 GMT |
|
 |
Jack Klei #3 / 4
|
 Bitfields vs. masking
On Sat, 24 Aug 2002 10:00:37 GMT, "Spehro Pefhany"
Quote: > The objective is to have some status bits that can be accessed either as a > group (say, to set them all to a known state) or individually. > I can see two obvious ways to do this in C: > a) Use macros like those in the faq, eg. > /* BITSET and BITMASK are defined already */ > enum {bluestatus, redstatus}; > unsigned char stat=0; > BITSET(stat, bluestatus); > if (0 != BITMASK(stat, redstatus)) { /* do something */}; > b) union > { > unsigned char wchar; > struct > { > /* bit order in a bit field is implementation dependent */ > unsigned bluestatus: 1; > unsigned redstatus: 1; > } bits; > } stat; > stat.wchar = 0; /* this is portable */ > stat.wchar = 1; /* clear redstatus, set bluestatus..this isn't */ > stat.bits.bluestatus = 1; > if (0 != stat.bits.redstatus) {/* do something */}; > Which is better, and why? b) seems much more readable, but has possible > portability issues, as noted. > Is there some (glaringly obvious(?)) better way of doing it? > Best regards, > Spehro Pefhany
Even assuming CHAR_BIT == 8, consider the very simple case where: 1. The compiler allocates a 16 or 32 bit integer object to hold your bitfield (remember, there is no guarantee that it will use 8 bits to hold a bit field with fewer than 8 bits). 2. The compiler allocates bit fields from the most significant bit downward, not from the least significant bit upward. In those circumstances, even the expression stat.wchar = 0 does not have the effect you seem to think it does. -- Jack Klein Home: http://JK-Technology.Com FAQs for comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html comp.lang.c++ http://www.parashift.com/c++-faq-lite/ alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq
|
Thu, 10 Feb 2005 10:53:07 GMT |
|
 |
Spehro Pefhan #4 / 4
|
 Bitfields vs. masking
Quote: > Even assuming CHAR_BIT == 8, consider the very simple case where: > 1. The compiler allocates a 16 or 32 bit integer object to hold your > bitfield (remember, there is no guarantee that it will use 8 bits to > hold a bit field with fewer than 8 bits).
Yes. Quote: > 2. The compiler allocates bit fields from the most significant bit > downward, not from the least significant bit upward.
Yes, this is a possiblility according to the standard. Quote: > In those circumstances, even the expression stat.wchar = 0 does not > have the effect you seem to think it does.
Ah, okay, I see what you mean. It could legitimately set the lower 8 bits to zero and leave the upper ones unaffected. Sounds like a potential can of worms. Thanks for the responses, I'll have to carefully consider what to do in this case. Best regards, Spehro Pefhany -- "it's the network..." "The Journey is the reward"
Embedded software/hardware/analog Info for designers: http://www.speff.com 9-11 United we Stand
|
Thu, 10 Feb 2005 22:25:03 GMT |
|
|
|