The problem with bit-fields

Programming, for all ages and all languages.
Post Reply
User avatar
Zenith
Member
Member
Posts: 224
Joined: Tue Apr 10, 2007 4:42 pm

The problem with bit-fields

Post by Zenith »

I've been working on my OS for quite a while now. Looking at some other people's code, I saw some C code that I didn't recognize: bit-fields! :shock:

So I figured out what they were, etc... but they really bug me and I'm unsure if using them is a good idea.

Pros:
- Makes things easier (more organized)
- Lets the compiler do the bit accessing for you

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?
"Sufficiently advanced stupidity is indistinguishable from malice."
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

Cons:
- Bit-fields HAVE to be part of an unsigned/signed int Sad
Why is this a problem?
- 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?)
Endianness is specific to the target architecture (the arch the compiler is compiler *for*, not *on*). If you recompile for a target architecture with a different endianness you're pretty much always going to run into problems. Anyway IIRC bitfields don't have any endianness problems.
User avatar
bewing
Member
Member
Posts: 1401
Joined: Wed Feb 07, 2007 1:45 pm
Location: Eugene, OR, US

Post by bewing »

And it makes it less likely for someone who understands bitfields to make a coding error.
And it makes it more likely that someone unfamiliar with bitfields will totally screw up your code -- because the bitfield syntax is ugly as hell.
And your code would not compile on an old K&R C compiler -- since bitfields are a dangling ANSI add-on.
mrvn
Member
Member
Posts: 43
Joined: Tue Mar 11, 2008 6:56 am

Re: The problem with bit-fields

Post by mrvn »

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
Life - Don't talk to me about LIFE!
So long and thanks for all the fish.
User avatar
Zenith
Member
Member
Posts: 224
Joined: Tue Apr 10, 2007 4:42 pm

Re: The problem with bit-fields

Post by Zenith »

I decided that I'll only use bitfields where it would be easier to use them compared to bitmasks - most likely for page directories/tables, possibly segment descriptors, and idt stuff, but that's it.

I still find bitmasks easier to work with...
mrvn wrote: 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.
Yes, but unsigned/signed int is the only standard-conforming one. Using other integer types are compiler extensions and might not supported on all compilers/architectures.
"Sufficiently advanced stupidity is indistinguishable from malice."
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: The problem with bit-fields

Post by Solar »

mrvn wrote: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.
Hear ye! Hear ye!

:!: Excellent design decision! :!:
Every good solution is obvious once you've found it.
User avatar
os.hacker64
Member
Member
Posts: 149
Joined: Mon Feb 11, 2008 4:43 pm
Location: Limbo City,Afterlife

Post by os.hacker64 »

speaking of bitfields, how does gcc order them, what is the most significant bit in the struct, how do I control this.
Kanu Operating System
Working on:Paging and Multitasking

BURN /\/\1(40$0|=7
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

os.hacker64 wrote:speaking of bitfields, how does gcc order them, what is the most significant bit in the struct, how do I control this.
By the order of the defined variables in the struct...
Post Reply