4 ms·
No. Please. Struct bitfields may be useful to save memory (e.g. 1 bit for boolean-like variable) but don't rely on it when accessing register data or implentin
by kbumsik 9y ago
No. Please.
Struct bitfields may be useful to save memory (e.g. 1 bit for boolean-like variable) but don't rely on it when accessing register data or implenting protocols.
The biggest issue with struct bitfields is that its implementation is ABI-specific, meaning it is not even compiler-specific. For example, his "Application #2: Implementing Protocols" example is not portable across archtectures because the order of bits are swapped when compiling for a Big-endian CPU. We should use bitwise operations for this purpose.
Look at his last example, "Application #3: Access to MCU Registers". The SDK source code he mentioned does not use bitfield but bitwise operations to access register bits.
- kazinator 9y ago"ABI-specific" should be broader, more portable than "compiler specific"; different compilers must implement the same ABI on a given system (or else not interoperate). Of course bitfields are endian-specific, but two different compilers should agree on them for a given endian.
- eecsninja 9y agoBitfields are too useful of a feature not to use. The solution is simple: add a unit test to verify that setting one bitfield to all 1's will result in the overall 32-bit or 64-bit word having the expected value. Add a comment explaining this too. That will catch nonportable use in the future.
- AnimalMuppet 9y agoBut for embedded software, ABI-specific isn't (usually) an issue. I have never seen an embedded project that changed either architectures ore compilers in the middle. In embedded, once you start the project, you're almost always using the same tooling until it dies. (Even moving to the latest rev of a compiler is rarely done, in my experience.) So you can use bitfields, however they have to be defined to work with your compiler/architecture/hardware, and expect that they're going to continue to work for the duration. (Whether bitfields are a bad idea for other reasons is outside the scope of my comment.)
- mikeash 9y agoABI-specific means you can count on the behavior as long as you know the target hardware and OS. If you’re twiddling registers, it’s highly likely you know the target.
- deleted 9y ago[deleted]
- squarefoot 9y agoThey're perfectly usable between different architectures, languages, operating systems and compilers, if precautions are taken. I did this many moons ago between big and little endian machines both in C for various Unixes and Delphi under Windows to exchange data in a network. Of course we used ntoh() and hton() functions extensively, #pragmas to adapt data alignment and similar features under Delphi. The use of unions allowed us to use a single buffer for each packet received going to the relevant part after matching the header which described what was being sent. All worked perfectly for years on SCO/Unix, IBM AIX, Linux and Windows.