karekare0 wrote:
Cons:
- Bit-fields HAVE to be part of an unsigned/signed int

- Endianness is implementation specific (but for an x86 OS (little-endian), it wouldn't matter since anyone who compiles it on a big-endian architecture would be using a cross compiler, right?)
Any ideas? Who uses bit-fields and who uses bit-masks, and why?
Bit-fields don't have to be part of an unsigned/signed int. They only need to be part of an integer type. And the type used matters in how the compiler can store bits. Lets say you want to use a bitfield for 16bit graphics output. So you have 5 bits per color channel. That fits into uin8_t just fine. So lets define out color like this:
Code: Select all
struct Color {
uint8_t r:5;
uint8_t g:5;
uint8_t b:5;
};
But surprise, surprise. That structure will use 3 bytes and not 2 like we wanted. The problem here is that bit fields can only be combined up to the size of the integer type used. You can't fit 2 5-bit integers into 8 bit. The right structure would have been:
Code: Select all
struct Color {
uint16_t r:5;
uint16_t g:5;
uint16_t b:5;
};
This gives a nice 2 bytes size and hopefully the right offsets for each color. How to define your bitfileds so they exactly match the bit layout you need will be compiler and architecture specific. Like many other things in your OS. So, as long as you are aware of this, it hardly makes things worse.
I tried using bitfields in my own code and kind of decided against it though. While their use is verry nice the code they generate is not. I defined a bitfield describing the Page Table Entry for amd64 and then created some page table entries to map pages. The whole structure is 64bit so this should result in a simple instruction loading a 64bit value, or so I hoped. Instead the compiler would generate code to set individual bits in the field, sometimes combining a few bits, sometimes not.
As a solution I used an union of uint64_t and the bitfield. That way I can access the full page table entry in one go, extract a set of flags by masking bits etc on the one hand and on the other hand I can use the bitfield to access indivdual flags with a nice syntax:
MfG
Goswin