By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,389 Members | 1,844 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,389 IT Pros & Developers. It's quick & easy.

How to use bitfields?

P: n/a
Who can explain to me what bitfields are and how to use them in
practice? I would need a fairly detailed explaination, I would be a
newbie to advanced C programming features. What are the advantages of
using bitfields?

cman

Feb 18 '07 #1
Share this Question
Share on Google+
9 Replies


P: n/a
cman wrote:
Who can explain to me what bitfields are and how to use them in
practice? I would need a fairly detailed explaination, I would be a
newbie to advanced C programming features. What are the advantages of
using bitfields?
A bit field is an element of a struct or union, having an
integer type but a specified "width," or number of bits. You
can have, for example, a three-bit signed integer or a five-bit
unsigned integer, and so on. There are restrictions on what
"underlying types" can be used, and on what widths are possible.
Also, it is not possible to form a pointer to a bit field (hence,
it is not possible to create an array of bit fields).

Bit fields have few advantages in portable code. In non-
portable code they are sometimes used to build a struct whose
layout corresponds to an externally-defined format of some
kind (e.g., the sign, exponent, and significand of a `float').

Recommendation: Learn to recognize them in code you read,
because you will encounter them, but avoid them in new code
that you write.

--
Eric Sosman
es*****@acm-dot-org.invalid
Feb 18 '07 #2

P: n/a
cman wrote:
Who can explain to me what bitfields are and how to use them in
practice? I would need a fairly detailed explaination, I would be a
newbie to advanced C programming features.
Bitfields are not an "advanced" feature of C. In fact, there is not much
difference with other integer types beside their bit size.
What are the advantages of using bitfields?
Memory usage, essentially, at the very lowest possible level. Note that
we could always do without bitfields anyway (by using bitwise operators
like & and |). It's just for readability that bitfields are used.

They are often used to provide an intuitive interface to an underlying
IO register or low-level structure. This way, you use the same semantic
to access values as any other type. Consider, as an example, a pixel
definition in some 16 bits ARGB format:

#include <stdio.h>
#include <stdint.h// C99 uint16_t

struct ARGB1555 {
union {
uint16_t value;
struct {
unsigned int blue : 5;
unsigned int green : 5;
unsigned int red : 5;
unsigned int alpha : 1;
} comp;
} u;
};

int main(void)
{
struct ARGB1555 pixel;
pixel.u.comp.red = 20;
pixel.u.comp.green = 22;
pixel.u.comp.blue = 7;
pixel.u.comp.alpha = 1;
printf( "red: %d, green: %d, blue: %d, alpha: %d\n",
pixel.u.comp.red,
pixel.u.comp.green,
pixel.u.comp.blue,
pixel.u.comp.alpha );

return 0;
}

This is far more readable than this uggly equivalent machine dependant crap:

int main(void)
{
struct ARGB1555 pixel;
pixel.u.value = (1 << 15) | (20 << 10) | (22 << 5) | 7;
printf( "red: %d, green: %d, blue: %d, alpha: %d\n",
(pixel.u.value >10) & 0x1f,
(pixel.u.value >5) & 0x1f,
pixel.u.value & 0x1f,
(pixel.u.value >15) & 0x1 );

return 0;
}

Of course, you may use constants for components instead of bare
hardcoded values (so porting the code would just have to redefine them,
like bitfields), but anyway this would still make the code harder to
read and even a lot harder to write.

Also, think about integer operations... even the simplest would be a
bargain without bitfields. Just consider:

pixel.u.comp.blue += 12;

Doing this simple operation without bitfields should be done with great
care in complex and hard to read expressions. Most programmers would
certainly introduce a temporary variable to handle it more easily, but
still. By using bitfields, you make the code a lot more readable while
the compiler takes care of all the masking and shifting bargain.

--
R.N.
Feb 18 '07 #3

P: n/a
Radamanthe <te****@free.deleteme.frwrites:
cman wrote:
>Who can explain to me what bitfields are and how to use them in
practice? I would need a fairly detailed explaination, I would be a
newbie to advanced C programming features.

Bitfields are not an "advanced" feature of C. In fact, there is not
much difference with other integer types beside their bit size.
>What are the advantages of using bitfields?

Memory usage, essentially, at the very lowest possible level. Note
that we could always do without bitfields anyway (by using bitwise
operators like & and |). It's just for readability that bitfields are
used.

They are often used to provide an intuitive interface to an underlying
IO register or low-level structure. This way, you use the same
semantic to access values as any other type. Consider, as an example,
a pixel definition in some 16 bits ARGB format:
[snip]

Yes, that kind of thing is common -- but it only works if the compiler
lays out your bit fields in exactly the way you need it to, matching
the externally imposed data layout. The standard says very little
about how bit fields are laid out. On the other hand, for this kind
of low-level code, depending on the behavior of a particular compiler
(which likely does document how it lays out bit fields) may not be a
problem.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Feb 18 '07 #4

P: n/a
On Feb 18, 11:24 pm, Radamanthe <tek...@free.deleteme.frwrote:
...Note that
we could always do without bitfields anyway (by using bitwise operators
like & and |). It's just for readability that bitfields are used.
The compiler Sun used for the 68020 would use
the 68020's special bit-field op-codes for bitfields,
but not for the &/| equivalents. Any other compilers?

James

Feb 19 '07 #5

P: n/a
On Feb 18, 8:24 am, Radamanthe <tek...@free.deleteme.frwrote:
cman wrote:
What are the advantages of using bitfields?

Memory usage, essentially, at the very lowest possible level. Note that
we could always do without bitfields anyway (by using bitwise operators
like & and |). It's just for readability that bitfields are used.

They are often used to provide an intuitive interface to an underlying
IO register or low-level structure. This way, you use the same semantic
to access values as any other type. Consider, as an example, a pixel
definition in some 16 bits ARGB format:

#include <stdio.h>
#include <stdint.h// C99 uint16_t

struct ARGB1555 {
union {
uint16_t value;
struct {
unsigned int blue : 5;
unsigned int green : 5;
unsigned int red : 5;
unsigned int alpha : 1;
} comp;
} u;

};

int main(void)
{
struct ARGB1555 pixel;
pixel.u.comp.red = 20;
pixel.u.comp.green = 22;
pixel.u.comp.blue = 7;
pixel.u.comp.alpha = 1;
printf( "red: %d, green: %d, blue: %d, alpha: %d\n",
pixel.u.comp.red,
pixel.u.comp.green,
pixel.u.comp.blue,
pixel.u.comp.alpha );

return 0;

}

This is far more readable than this uggly equivalent machine dependant crap:

int main(void)
{
struct ARGB1555 pixel;
pixel.u.value = (1 << 15) | (20 << 10) | (22 << 5) | 7;
printf( "red: %d, green: %d, blue: %d, alpha: %d\n",
(pixel.u.value >10) & 0x1f,
(pixel.u.value >5) & 0x1f,
pixel.u.value & 0x1f,
(pixel.u.value >15) & 0x1 );

return 0;

}
Why do you describe the second version as "machine dependent crap"?
Your use of bitfields in the first example is entirely implementation
dependent, since very little about the layout of bitfields is defined
in C. One compiler may lay them out from the most significant bit
down, another from the least significant up, for example. If you do
this with bitfields, you may need to re-implement your code for each
different compiler or target.

The second method, however, is implementation and machine independent
and entirely portable (in principle - I've not checked the details of
your example). Code written in this way is portable between compilers
for the same target, and often across different targets.

Feb 19 '07 #6

P: n/a
J. J. Farrell wrote:
On Feb 18, 8:24 am, Radamanthe <tek...@free.deleteme.frwrote:
>cman wrote:
>>What are the advantages of using bitfields?
Memory usage, essentially, at the very lowest possible level. Note that
we could always do without bitfields anyway (by using bitwise operators
like & and |). It's just for readability that bitfields are used.

They are often used to provide an intuitive interface to an underlying
IO register or low-level structure. This way, you use the same semantic
to access values as any other type. Consider, as an example, a pixel
definition in some 16 bits ARGB format:

#include <stdio.h>
#include <stdint.h// C99 uint16_t

struct ARGB1555 {
union {
uint16_t value;
struct {
unsigned int blue : 5;
unsigned int green : 5;
unsigned int red : 5;
unsigned int alpha : 1;
} comp;
} u;

};

int main(void)
{
struct ARGB1555 pixel;
pixel.u.comp.red = 20;
pixel.u.comp.green = 22;
pixel.u.comp.blue = 7;
pixel.u.comp.alpha = 1;
printf( "red: %d, green: %d, blue: %d, alpha: %d\n",
pixel.u.comp.red,
pixel.u.comp.green,
pixel.u.comp.blue,
pixel.u.comp.alpha );

return 0;

}

This is far more readable than this uggly equivalent machine dependant crap:

int main(void)
{
struct ARGB1555 pixel;
pixel.u.value = (1 << 15) | (20 << 10) | (22 << 5) | 7;
printf( "red: %d, green: %d, blue: %d, alpha: %d\n",
(pixel.u.value >10) & 0x1f,
(pixel.u.value >5) & 0x1f,
pixel.u.value & 0x1f,
(pixel.u.value >15) & 0x1 );

return 0;

}

Why do you describe the second version as "machine dependent crap"?
Because I was too lazy to write a more clean version, with mask and
shift constants instead of hardcoded values (so it would have the same
degree of portability than the bitfield version, at least).

The point was to demonstrate the readability of bitfields. I could have
gone a lot further.
Your use of bitfields in the first example is entirely implementation
dependent, since very little about the layout of bitfields is defined
in C.
Of course it is implementation dependent ! This is all about low-level
assumptions. But only THIS definition has to be changed, not the
potential thousands lines of code using it everywhere else.

There is simply no way in C or any other language (maybe fragment
shaders, but this is not as flexible as C) to make machine independant
code for such things, as for many others. If you want speed (and believe
me: you WANT speed when dealing with screen devices), this is the best &
least you can do because anyway, you know that it will have to be ported
to be efficient enough.
One compiler may lay them out from the most significant bit
down, another from the least significant up, for example. If you do
this with bitfields, you may need to re-implement your code for each
different compiler or target.
The bitfield definition code only. All the rest is unchanged and THAT is
the point.
The second method, however, is implementation and machine independent
and entirely portable (in principle - I've not checked the details of
your example).
No, it isn't (like the bitfield version) when you're not alone in your C
universe and you communicate with devices somewhere else millions of
times per second. C is not only about dealing with databases used by C
programs only. That would be so simple.

I don't use C because of its portability (though this is welcome), but
because it is the only language that allow me to do pseudo-assembly
low-level code very tied to the hardware in such a way that I don't have
to rewrite everything for each target. In my pov, it is the greatest
power of C and the main reason why I stick to it (or C++ eventually).
Code written in this way is portable between compilers
for the same target, and often across different targets.
Is this a debate around 99.98% versus 99.99% portability ? And what is a
target for you ? A "C machine" ? I wish computers to be only "C
machines", I would have far less problems, but halas, my output device
would not be able to draw pixels anyway, and this example would
certainly have no sense.

--
R.N.
Feb 19 '07 #7

P: n/a
Radamanthe <te****@free.deleteme.frwrites:
J. J. Farrell wrote:
[...]
>Your use of bitfields in the first example is entirely implementation
dependent, since very little about the layout of bitfields is defined
in C.

Of course it is implementation dependent ! This is all about low-level
assumptions. But only THIS definition has to be changed, not the
potential thousands lines of code using it everywhere else.

There is simply no way in C or any other language (maybe fragment
shaders, but this is not as flexible as C) to make machine independant
code for such things, as for many others. If you want speed (and
believe me: you WANT speed when dealing with screen devices), this is
the best & least you can do because anyway, you know that it will have
to be ported to be efficient enough.
<OT>
In fact, there are machine-independent ways to do this in *some*
languages. In Ada, for example, you can use a representation clauses
to specify the exact layout of a record (struct) type, or you can use
slices of a packed Boolean array.
</OT>

[...]
>Code written in this way is portable between compilers
for the same target, and often across different targets.

Is this a debate around 99.98% versus 99.99% portability ? And what is
a target for you ? A "C machine" ? I wish computers to be only "C
machines", I would have far less problems, but halas, my output device
would not be able to draw pixels anyway, and this example would
certainly have no sense.
Bit field layout is likely to be affected by byte ordering, which
definitely varies from one platform to another. I suspect there are
other variations beyond that, such as whether bit fields can cross a
word boundary, and just what a "word" is.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Feb 19 '07 #8

P: n/a
Keith Thompson wrote:
Radamanthe <te****@free.deleteme.frwrites:
>J. J. Farrell wrote:
[...]
>>Your use of bitfields in the first example is entirely implementation
dependent, since very little about the layout of bitfields is defined
in C.
Of course it is implementation dependent ! This is all about low-level
assumptions. But only THIS definition has to be changed, not the
potential thousands lines of code using it everywhere else.

There is simply no way in C or any other language (maybe fragment
shaders, but this is not as flexible as C) to make machine independant
code for such things, as for many others. If you want speed (and
believe me: you WANT speed when dealing with screen devices), this is
the best & least you can do because anyway, you know that it will have
to be ported to be efficient enough.

<OT>
In fact, there are machine-independent ways to do this in *some*
languages. In Ada, for example, you can use a representation clauses
to specify the exact layout of a record (struct) type, or you can use
slices of a packed Boolean array.
</OT>
Nice. Is it easily merged into C code or should I rewrite everything in
Ada ? :)
>>Code written in this way is portable between compilers
for the same target, and often across different targets.
Is this a debate around 99.98% versus 99.99% portability ? And what is
a target for you ? A "C machine" ? I wish computers to be only "C
machines", I would have far less problems, but halas, my output device
would not be able to draw pixels anyway, and this example would
certainly have no sense.

Bit field layout is likely to be affected by byte ordering, which
definitely varies from one platform to another. I suspect there are
other variations beyond that, such as whether bit fields can cross a
word boundary, and just what a "word" is.
You can use padding fields to sort it out. That's not to say the
compiler would not be conform if it would not permit to represent the
required bits layout anyway, but it would be obsolete in the context of
adressing a given device at a such low level, thus losing a great
advantage of C.

--
R.N.
Feb 19 '07 #9

P: n/a
Radamanthe <te****@free.deleteme.frwrites:
Keith Thompson wrote:
[...]
><OT>
In fact, there are machine-independent ways to do this in *some*
languages. In Ada, for example, you can use a representation clauses
to specify the exact layout of a record (struct) type, or you can use
slices of a packed Boolean array.
</OT>

Nice. Is it easily merged into C code or should I rewrite everything
in Ada ? :)
<OT>
Ada provides mechanisms for interfacing to C. The syntax is very
different, so you can't mix them at the source level. An Ada frontend
is an optional part of gcc.

It's up to you (and entirely off-topic) whether you want to use Ada.
</OT>

[...]
>Bit field layout is likely to be affected by byte ordering, which
definitely varies from one platform to another. I suspect there are
other variations beyond that, such as whether bit fields can cross a
word boundary, and just what a "word" is.

You can use padding fields to sort it out. That's not to say the
compiler would not be conform if it would not permit to represent the
required bits layout anyway, but it would be obsolete in the context
of adressing a given device at a such low level, thus losing a great
advantage of C.
What do you mean by "padding fields"?

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Feb 20 '07 #10

This discussion thread is closed

Replies have been disabled for this discussion.