6 ms·
I'm not sure this guy really knows what he is talking about. Bit fields are almost universally hated and not allowed in style guides. The Arm guide he links to
by barbegal 9y ago
I'm not sure this guy really knows what he is talking about. Bit fields are almost universally hated and not allowed in style guides. The Arm guide he links to states:
> Please note that peripheral locations should not be accessed using __packed structs (where unaligned members are allowed and there is no internal padding), or using C bitfields.
Using bit fields for protocols is even more ill advised because often you may wish to implement the same code across different devices using the same protocol but the compilers will arrange the bit fields differently.
The only valid example he gives is the last one which is the correct way to do it: a struct made up of 32 bit values. This makes sure that everything is 4 byte aligned and the processor can access those variables in a single instruction.
If you wish to use the dense packing of bit fields but without the compiler ambiguity then you should use explicit bit shifting and bit masking (again shown in his last example)
- ausjke 9y agoAgree. For Embedded coding suggestions you have to know what you are talking about really well otherwise it could be just misleading. Bit fields should be avoided even for resource restricted MCUs, period.
- kevin_thibedeau 9y agoStyle guides are universally written for systems programming where RAM is in abundance. For embedded, memory usage matters and packing data in is a thing. It is ill advised because of the portability traps but portability is low on the priority chain if you just have to make it work. Any decent compiler will do what you want if you pad out the unused bits with a reserved field to guarantee alignment. Reminds me of the C# jockey who complained endlessly about the bitfields (using manual masking) I put into an IoT data structure that was supposed to be kept as small as possible to minimize hosting costs. He had no clue about how to use bitwise operations to extract bits. They managed to bloat that into a horrendous monstrosity but I wasn't going to play their game. If they had their way, a half dozen bits packed into a 32-bit word would have consumed 20x more space with unnecessary schema boilerplate.
- tzahola 9y agoYou mean you didn’t use JSON??? The horror...
- jcranmer 8y agoThere's a distinction to be made between packing bits in a structure and using bitfields to access packed bits (as opposed to doing the shifts and masks manually). From a compiler writer's perspective, bitfields are one of the worst things ever proposed for a standard. The nonportability of which way bits are laid out is the least of their problems. The logic of how you actually pack bits in the struct is surprisingly nontrivial. The underlying semantics of bitfields are so weird pretty much every time they could be used, they need to be special-cased--both in the standard sense and in the implementation sense. This means that using bitfields requires navigating a field of landmines of potential compiler (or, worse, spec) bugs.
- eecsninja 8y agoThe solution is just to make sure you have padding fields that result in an overall size that's a multiple of however many bits e.g. 32 or 64 bits. Use static_assert() to enforce the size. See my earlier comment about unit testing too.
- jcranmer 8y agoWell, to have a good chance of avoiding the landmines, you need to: * Pack the bitfields in a struct all by themselves. Don't mix bitfields and non-bitfields in the same struct. (This means that you limit the scope of insanity to other bitfields, not potentially expanding it to other regular fields). * Make sure that the underlying type of all the bitfields within the struct have the same type. And make it be unsigned. * Pad the bitfields to the appropriate size of the type. * Only access the bitfields by copying them to/from the appropriate local variable (you don't want to trip code up on the bitfields-aren't-quite-the-type-they-say-they-are logic).
- eecsninja 8y ago