They can be, if done right, but then I have to remember the names of all the helper functions and macros. :-) An IDE can auto-complete bitfield names.
>Still more work for people reading the code, though since there are a lot of hidden assumptions behind that deceptively simple "=" than with an explicit mask and shift.
Depends on the platform. IIRC on ARM a bitfield access is masking and shifting, only done by the compiler instead of me. With optimized code I often have to look at the disassembly anyway if I want to know what's really going on.
ARM supports native bitfield loading[1], extraction[2] and clearing[3].
1 - https://developer.arm.com/documentation/ddi0602/2022-03/Base...
2 - https://developer.arm.com/documentation/ddi0602/2022-03/Base...
3 - https://developer.arm.com/documentation/ddi0602/2022-03/Base...
Many of them get it right.
#define CLEARBIT(a,p) = ((a) &= ~(1 << (p)))
might not work correctly if your datatype is something "exotic" like a long. An inlined function might be the better choice.Otherwise you would need to define specific macros again:
#define CLEARBITLONG(a,p) = ((a) &= ~(1L << (p)))
These bugs can steal hours of your time, especially on embedded systems where debugging is less accessible. #define CLEARBIT(a,p) = ((a) &= ~((typeof(a))1 << (p)))