Additionally, for shorter than one byte integers nested inside registers this is ideal. You can just use :2 instead and you've got yourself 0 - 3 or :3 for 0 - 7 etc!
I wonder if it's as fast though............... with bit fields inorder to "get" a bit from a byte it must do a bit-wise then use that value, not just use the value. What do you think ?
I think it's just going to mask it off as we do manually at the moment.
Each and every time I set a bit, I have to use or or and and a mask. It'll just be doing this behind the scenes. We can write some test code to try it out and compare the binary/assembly, but it'll probably be the same or better. Even if it's worse, it's going to clean up the code no end!
The code above runs on a 2mhz cpu... this guy cares about speed a LOT. So I doubt it's slow for that reason too!
I did try to search for boolean types early on, but I failed to find this, mostly because its not a boolean type, really.
thats the beauty of bitfield .. you lean on the compiler to do all the masking/shifting for you .. but I think each has their place.
'old-school' firmware folks that I know hate them with a passion .. because they 'can't trust the compiler'. When I point out all their masking/shifting screwups, they get even madder .. because they have never been able to point back and show me where the compiler has ever screwed up on me.
I make personal exceptions for clarity, here's an example from some code i just did a couple of days ago. it's for some dead simple pin setup code. this is just for a couple of simple single bit fields in a register (which has more fields) but I want to keep the example short:
I can construct things like:
func( GPIO | OUTPUT_MODE | READBACK_ENABLE ); // 'descriptive'
vs
func( GPIO | OUTPUT_BUFFER_ENABLE | INPUT_BUFFER_ENABLE ); // 'dry'
which mean the same thing ...
as an alternative, using the bitstruct way, ponder this ... how would you handle r-m-w operations atomically on a register when you had to setup multiple fields (i can give an example of how I would do it) ? sometimes the code gets a bit longer than you anticipated .. but its safer since the compiler is working for you.
I also have some other things I do for multi-bit fields to get some asserts() and 'contract-like' programming into my code .. which all compiles out w/NDEBUG like all of the other asserts.
you MAY also run into ordering issues if you use different compilers within the same platform - its considered a highly unportable construct to be using .. so do you trade the danger of shifting/masking across platforms or do you just change the ordering of your struct ?? tradeoffs everywhere in C.
did I go way off track on this ? tell me where to expand if you're interested. I can throw in some 'non-sensitive' real world current examples.
I'm unsure about the number of bus cycles those intructions take, but assuming its 1 each or equal between the two, bitfields are slower and regardless they are definitely bigger :-/
fred@roadeee [07:39:54]:src$ l masks/firmware/
total 900
-rwxr-xr-x 1 fred fred 150742 2010-05-30 21:31 freeems-0.1.1-SNAPSHOT-LT1-360-8.s19
-rwxr-xr-x 1 fred fred 150622 2010-05-30 21:31 freeems-0.1.1-SNAPSHOT-MiataNB.s19
-rwxr-xr-x 1 fred fred 151860 2010-05-30 21:31 freeems-0.1.1-SNAPSHOT-MissingTeeth.s19
-rwxr-xr-x 1 fred fred 153666 2010-05-30 21:31 freeems-0.1.1-SNAPSHOT-NipponDenso.s19
-rwxr-xr-x 1 fred fred 152220 2010-05-30 21:31 freeems-0.1.1-SNAPSHOT-Simple.s19
-rwxr-xr-x 1 fred fred 150622 2010-05-30 21:31 freeems-0.1.1-SNAPSHOT-Subaru-36-2-2-2.s19
fred@roadeee [07:39:55]:src$ l bitfield/firmware/
total 900
-rwxr-xr-x 1 fred fred 150768 2010-05-30 21:09 freeems-0.1.1-SNAPSHOT-LT1-360-8.s19
-rwxr-xr-x 1 fred fred 150634 2010-05-30 21:09 freeems-0.1.1-SNAPSHOT-MiataNB.s19
-rwxr-xr-x 1 fred fred 151872 2010-05-30 21:09 freeems-0.1.1-SNAPSHOT-MissingTeeth.s19
-rwxr-xr-x 1 fred fred 153754 2010-05-30 21:09 freeems-0.1.1-SNAPSHOT-NipponDenso.s19
-rwxr-xr-x 1 fred fred 152232 2010-05-30 21:09 freeems-0.1.1-SNAPSHOT-Simple.s19
-rwxr-xr-x 1 fred fred 150634 2010-05-30 21:09 freeems-0.1.1-SNAPSHOT-Subaru-36-2-2-2.s19
Every single platform I've written to it always comes out bigger ... except for one .. if was on 8051. Mostly, I think its an optimization issue and the '51 compiler devs probably put the extra effort in to ensure it was still efficient.
I bet if you targeted a platform like ia32 .. someone has put the effort into the gcc optimizer.