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

Bit shifting vs Bitfields

P: n/a
Hello All,

I am writing an application which receives a word which is a bitmap. I
have created a word typedef which contains a bitfield defining each
bit. however, I was wondering however if it would be better to write a
macro to access each bit instead of the bitfield.

I have read the C-FAQ on bit fields, but was wondering if there were
any advantages/disadvantages to using bit shifting. To my mind I think
using bitfields are more logical and easier to read and use but have a
feeling it is slower than bit shifting.

Can anyone enlighten me on this subject?

Regards,

Richard

Jun 13 '06 #1
Share this Question
Share on Google+
18 Replies


P: n/a
ri*******@latter.demon.co.uk wrote:
Hello All,

I am writing an application which receives a word which is a bitmap. I
have created a word typedef which contains a bitfield defining each
bit. however, I was wondering however if it would be better to write a
macro to access each bit instead of the bitfield.

I have read the C-FAQ on bit fields, but was wondering if there were
any advantages/disadvantages to using bit shifting. To my mind I think
using bitfields are more logical and easier to read and use but have a
feeling it is slower than bit shifting.

Don't speculate, profile!

I'm a bit field fan for the reasons you mention and whenever I've
bothered to look, the compiler generated very tight code to access them.

Just make sure you don't run into any endian issues.

--
Ian Collins.
Jun 13 '06 #2

P: n/a
On 13 Jun 2006 01:38:47 -0700, ri*******@latter.demon.co.uk wrote in
comp.lang.c:
Hello All,

I am writing an application which receives a word which is a bitmap. I
have created a word typedef which contains a bitfield defining each
bit. however, I was wondering however if it would be better to write a
macro to access each bit instead of the bitfield.
Maybe it would, maybe not.
I have read the C-FAQ on bit fields, but was wondering if there were
any advantages/disadvantages to using bit shifting. To my mind I think
using bitfields are more logical and easier to read and use but have a
feeling it is slower than bit shifting.
Why do you care which method is faster or slower? You shouldn't care
at all until the following program returns TRUE:

enum { FALSE, TRUE } BOOL;

BOOL should_I_worry_about_speed(void)
{
BOOL result = FALSE;

if (this_part_of_my_program_is_tested_and_verified_co rrect()
&& my_program_is_finished_and_works_correctly()
&& my_correct_program_runs_too_slowly()
&& I_have_verified_this_code_is_a_bottleneck())
/* then and only then */
{
result = TRUE;
}

return result;
}

Of course, you need to implement the four functions called. Or even
better, treat this as pseudo code and just answer the questions
yourself. If, and only if, the answers to all four questions are
true, then you can start thinking, and testing, whether bit fields are
faster than bit masks, or vice-versa.
Can anyone enlighten me on this subject?


Even if all the above answers are true, the only way to know whether
bit fields or bit masks are faster on your particular compiler and
processor is to build test code both ways and time it.

I have seen processors that have machine language instructions that
support bit-field manipulation, and C compilers that use them, with
the result that code using bit fields executes faster than code using
bit masks. And I have seen platforms where the opposite is true.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Jun 13 '06 #3

P: n/a
"Jack Klein" <ja*******@spamcop.net> wrote
I have read the C-FAQ on bit fields, but was wondering if there were
any advantages/disadvantages to using bit shifting. To my mind I think
using bitfields are more logical and easier to read and use but have a
feeling it is slower than bit shifting.


Why do you care which method is faster or slower? You shouldn't care
at all until the following program returns TRUE:

enum { FALSE, TRUE } BOOL;

BOOL should_I_worry_about_speed(void)
{
BOOL result = FALSE;

if (this_part_of_my_program_is_tested_and_verified_co rrect()
&& my_program_is_finished_and_works_correctly()
&& my_correct_program_runs_too_slowly()
&& I_have_verified_this_code_is_a_bottleneck())
/* then and only then */
{
result = TRUE;
}

return result;
}

Of course, you need to implement the four functions called. Or even
better, treat this as pseudo code and just answer the questions
yourself. If, and only if, the answers to all four questions are
true, then you can start thinking, and testing, whether bit fields are
faster than bit masks, or vice-versa.
Can anyone enlighten me on this subject?


Even if all the above answers are true, the only way to know whether
bit fields or bit masks are faster on your particular compiler and
processor is to build test code both ways and time it.

I have seen processors that have machine language instructions that
support bit-field manipulation, and C compilers that use them, with
the result that code using bit fields executes faster than code using
bit masks. And I have seen platforms where the opposite is true.

Bitfields were once generally badly implemented.
There was a kind of vicious circle. Programmers used masks because the
bitfield code was slow, and complier writers didn't bother much to optimise
bitfields because they were rarely used.

I am sure whether this is still the case. Now that memory sizes are so
large, usually it doesn't make much sense to try to squash data into a
minimal number of bits.
--
Buy my book 12 Common Atheist Arguments (refuted)
$1.25 download or $7.20 paper, available www.lulu.com/bgy1mm
Jun 13 '06 #4

P: n/a

Malcolm wrote:
Bitfields were once generally badly implemented.
There was a kind of vicious circle. Programmers used masks because the
bitfield code was slow, and complier writers didn't bother much to optimise
bitfields because they were rarely used.

I am sure whether this is still the case. Now that memory sizes are so
large, usually it doesn't make much sense to try to squash data into a
minimal number of bits.


When I have used bit fields it has usually been to overlay a structure
on a register of some sort, i.e. status register, where certain bits or
groups of bits have certain meanings. To my mind this makes the code
much more readable. This sort of thing has nothing to do with memory
footprint.

Jun 14 '06 #5

P: n/a
In article <11*********************@i40g2000cwc.googlegroups. com>,
sw***********@gmail.com <sw***********@gmail.com> wrote:
When I have used bit fields it has usually been to overlay a structure
on a register of some sort, i.e. status register, where certain bits or
groups of bits have certain meanings. To my mind this makes the code
much more readable.


Bit-mapped registers are often defined in terms of value bits, but
bit fields are not, leading to a potential endian confusion and
non-portability.

On the other hand, status registers are not portable anyhow ;-)
--
Okay, buzzwords only. Two syllables, tops. -- Laurie Anderson
Jun 14 '06 #6

P: n/a

Walter Roberson wrote:
In article <11*********************@i40g2000cwc.googlegroups. com>,
sw***********@gmail.com <sw***********@gmail.com> wrote:
When I have used bit fields it has usually been to overlay a structure
on a register of some sort, i.e. status register, where certain bits or
groups of bits have certain meanings. To my mind this makes the code
much more readable.


Bit-mapped registers are often defined in terms of value bits, but
bit fields are not, leading to a potential endian confusion and
non-portability.

On the other hand, status registers are not portable anyhow ;-)


Yeah, in order for my code to need to be portable the custom ASIC will
need a respin. I don't see anyone spending the money on that and even
if they do they are likely not to change the processor due to the large
amount of existing code.

Jun 14 '06 #7

P: n/a
Hello All,

Many thanks for the advice given. I was aware of the endian issue
before I posted this. My main query was if there were any benefits to
bit shifting rather than defining bit fields. I think my conclusion is
that unless you are porting code, defining bitfields are fine. I
would suggest that most ANSI compilers these days (I'm using gcc)
handle bitfields in the appropriate manner.

Thanks for all the contributions,

Regards,

Richard

sw***********@gmail.com wrote:
Walter Roberson wrote:
In article <11*********************@i40g2000cwc.googlegroups. com>,
sw***********@gmail.com <sw***********@gmail.com> wrote:
When I have used bit fields it has usually been to overlay a structure
on a register of some sort, i.e. status register, where certain bits or
groups of bits have certain meanings. To my mind this makes the code
much more readable.


Bit-mapped registers are often defined in terms of value bits, but
bit fields are not, leading to a potential endian confusion and
non-portability.

On the other hand, status registers are not portable anyhow ;-)


Yeah, in order for my code to need to be portable the custom ASIC will
need a respin. I don't see anyone spending the money on that and even
if they do they are likely not to change the processor due to the large
amount of existing code.


Jun 14 '06 #8

P: n/a
ri*******@latter.demon.co.uk wrote:
My main query was if there were any benefits to
bit shifting rather than defining bit fields. I think my conclusion is
that unless you are porting code, defining bitfields are fine. I
would suggest that most ANSI compilers these days (I'm using gcc)
handle bitfields in the appropriate manner.


I agree with the "appropriate handling", but not with "bit fields
unless porting".

I would use bit fields only if all of the following three assumptions
are true:

(a) It does not matter what bits are assigned to which field. [1]
(b) The size of the structure containing the bit fields is not
important. [2]
(c) The alignment of a bit field structure is not important. [3]

In most cases they are not, so I use masks + shifts.

(*) ISO/IEC 9899:1999(E):
6.7.2.1 Structure and union specifiers
....
Constraints
10 [2] An implementation may allocate any addressable storage unit
large enough to hold a bitfield.
If enough space remains, a bit-field that immediately follows another
bit-field in a structure shall be packed into adjacent bits of the
same unit. [2] If insufficient space remains, whether a bit-field that
does not fit is put into the next unit or overlaps adjacent units is
implementation-defined. [1] The order of allocation of bit-fields
within a unit (high-order to low-order or low-order to high-order) is
implementation-defined. [3] The alignment of the addressable storage
unit is unspecified.
Jun 14 '06 #9

P: n/a
Roberto Waltman wrote:
I would use bit fields only if all of the following three assumptions
are true:

(a) It does not matter what bits are assigned to which field. [1]
(b) The size of the structure containing the bit fields is not
important. [2]
(c) The alignment of a bit field structure is not important. [3]

In most cases they are not, so I use masks + shifts.


But even in cases when they are, those three conditions
don't supply a reason not to use masks and shifts,
so I always use masks and shifts.

--
pete
Jun 14 '06 #10

P: n/a
Roberto Waltman wrote:
ri*******@latter.demon.co.uk wrote:
My main query was if there were any benefits to
bit shifting rather than defining bit fields. I think my conclusion is
that unless you are porting code, defining bitfields are fine. I
would suggest that most ANSI compilers these days (I'm using gcc)
handle bitfields in the appropriate manner.

I agree with the "appropriate handling", but not with "bit fields
unless porting".

I would use bit fields only if all of the following three assumptions
are true:

(a) It does not matter what bits are assigned to which field. [1]
(b) The size of the structure containing the bit fields is not
important. [2]
(c) The alignment of a bit field structure is not important. [3]

In most cases they are not, so I use masks + shifts.

Have you ever come across a real world situation where any of these are
an issue?
--
Ian Collins.
Jun 14 '06 #11

P: n/a
In article <4f*************@individual.net>,
Ian Collins <ia******@hotmail.com> wrote:
Roberto Waltman wrote:
I would use bit fields only if all of the following three assumptions
are true:

Have you ever come across a real world situation where any of these are
an issue?


Yes...

20-ish years ago, I did a debugger/disassembler. The bit order
was important because some of the bits came from outside my control.
If I had programmed in terms of bitfields then the program would
have relied upon implementation-dependant behaviour.

But for my purposes, it turned out to be easier to write the code
in a table-driven manner, with bit masks and comparison values,
so the issue was avoided -- almost accidently, you might say.

Later I ported the disassembler part of the code to handle a completely
different architecture. If I had written in terms of bitfields the first
time, I would have had to rewrite to suit the compiler on the new
architecture; as it was, it was just a matter of populating the
table entries and writing code to handle the new addressing modes.
The table-driven code was again easier to handle in terms of bitmasks.
Somewhere in there is a point or two ;-) That
(1) if you do not control the generation and storage of all the
data to be manipulated, then the bitfield order and sizing would
indeed be important;
(2) that bitmasks are often easier to write for, and the code
generalizes and simplifies more readily
--
All is vanity. -- Ecclesiastes
Jun 14 '06 #12

P: n/a
Ian Collins <ia******@hotmail.com> wrote:
Roberto Waltman wrote:

I would use bit fields only if all of the following three assumptions
are true:

(a) It does not matter what bits are assigned to which field. [1]
(b) The size of the structure containing the bit fields is not
important. [2]
(c) The alignment of a bit field structure is not important. [3]

In most cases they are not, so I use masks + shifts.

Have you ever come across a real world situation where any of these are
an issue?


In embedded systems and communication protocols, all the time.

If I need, (drawing an example from a real project,) to set one of the
hardware registers controlling a communications device, where bit 0 is
an enable/disable flag, and bits 1 and 2 select one of four available
transfer rates, there is no portable way to do it using bitfields.

Lets assume the register is 8 bits wide, and I am using a 32 bit
processor which can access 8, 16, and 32 bit "storage units"

This struct

struct com_ctrl
{
unsigned int e:1; /* enable and rate. using one letter */
unsigned int r:2; /* identifiers to fit in the */
}; /* diagrams below */

could be mapped into any of these:

7 6 5 4 3 2 1 0
+-+-+-+-+-+---+-+
| | | | | | r |e|
+-+-+-+-+-+---+-+

7 6 5 4 3 2 1 0
+-+---+-+-+-+-+-+
|e| r | | | | | |
+-+---+-+-+-+-+-+

15 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+-+-+-+-+-+-+-+-+-+-+-+-+-+---+-+
| | | | | | | | | | | | | | r |e|
+-+-+-+-+-+-+-+-+-+-+-+-+-+---+-+

15 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+-+---+-+-+-+-+-+-+-+-+-+-+-+-+-+
|e| r | | | | | | | | | | | | | |
+-+---+-+-+-+-+-+-+-+-+-+-+-+-+-+

31 0 9 8 7 6 ... 9 8 7 6 5 4 3 2 1 0
+-+-+-+-+-+-+ ... +-+-+-+-+-+-+-+---+-+
| | | | | | | ... | | | | | | | | r |e|
+-+-+-+-+-+-+ ... +-+-+-+-+-+-+-+---+-+

31 0 9 8 7 6 ... 9 8 7 6 5 4 3 2 1 0
+-+---+-+-+-+ ... +-+-+-+-+-+-+-+-+-+-+
|e| r | | | | ... | | | | | | | | | | |
+-+---+-+-+-+ ... +-+-+-+-+-+-+-+-+-+-+
Not only the bit positions may not match, it is also impossible to
copy such a structure into the control register without risking
modifying adjacent registers.

Jun 14 '06 #13

P: n/a
Roberto Waltman wrote:
Ian Collins <ia******@hotmail.com> wrote:
Roberto Waltman wrote:
I would use bit fields only if all of the following three assumptions
are true:

(a) It does not matter what bits are assigned to which field. [1]
(b) The size of the structure containing the bit fields is not
important. [2]
(c) The alignment of a bit field structure is not important. [3]

In most cases they are not, so I use masks + shifts.

Have you ever come across a real world situation where any of these are
an issue?

In embedded systems and communication protocols, all the time.

If I need, (drawing an example from a real project,) to set one of the
hardware registers controlling a communications device, where bit 0 is
an enable/disable flag, and bits 1 and 2 select one of four available
transfer rates, there is no portable way to do it using bitfields.

Lets assume the register is 8 bits wide, and I am using a 32 bit
processor which can access 8, 16, and 32 bit "storage units"

This struct

struct com_ctrl
{
unsigned int e:1; /* enable and rate. using one letter */
unsigned int r:2; /* identifiers to fit in the */
}; /* diagrams below */

could be mapped into any of these:

But is it? I've never seen this happen with an embedded compiler. Bit
fields tend to be well documented in these..
7 6 5 4 3 2 1 0
+-+-+-+-+-+---+-+
| | | | | | r |e|
+-+-+-+-+-+---+-+

7 6 5 4 3 2 1 0
+-+---+-+-+-+-+-+
|e| r | | | | | |
+-+---+-+-+-+-+-+

15 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+-+-+-+-+-+-+-+-+-+-+-+-+-+---+-+
| | | | | | | | | | | | | | r |e|
+-+-+-+-+-+-+-+-+-+-+-+-+-+---+-+

15 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+-+---+-+-+-+-+-+-+-+-+-+-+-+-+-+
|e| r | | | | | | | | | | | | | |
+-+---+-+-+-+-+-+-+-+-+-+-+-+-+-+

31 0 9 8 7 6 ... 9 8 7 6 5 4 3 2 1 0
+-+-+-+-+-+-+ ... +-+-+-+-+-+-+-+---+-+
| | | | | | | ... | | | | | | | | r |e|
+-+-+-+-+-+-+ ... +-+-+-+-+-+-+-+---+-+

31 0 9 8 7 6 ... 9 8 7 6 5 4 3 2 1 0
+-+---+-+-+-+ ... +-+-+-+-+-+-+-+-+-+-+
|e| r | | | | ... | | | | | | | | | | |
+-+---+-+-+-+ ... +-+-+-+-+-+-+-+-+-+-+
Not only the bit positions may not match, it is also impossible to
copy such a structure into the control register without risking
modifying adjacent registers.

--
Ian Collins.
Jun 14 '06 #14

P: n/a
Ian Collins <ia******@hotmail.com> wrote:
Roberto Waltman wrote:
...
This struct

struct com_ctrl
{
unsigned int e:1; /* enable and rate. using one letter */
unsigned int r:2; /* identifiers to fit in the */
}; /* diagrams below */

could be mapped into any of these:
....But is it? I've never seen this happen with an embedded compiler. Bit
fields tend to be well documented in these..


I am not sure I understand you question. Any particular choice is
likely to be documented and stable for a particular compiler.
Any code relying on that choice is still not portable.

Use that communication device I used as an example in a different
product, with a different processor and compiler and the code may not
work anymore.

The same applies to the handling of fields in communication protocols
when messages are exchanged between separate processors.

The structure size problem can be a show stopper, documented or not.
Jun 14 '06 #15

P: n/a
Roberto Waltman <us****@rwaltman.net> writes:
ri*******@latter.demon.co.uk wrote:
My main query was if there were any benefits to
bit shifting rather than defining bit fields. I think my conclusion is
that unless you are porting code, defining bitfields are fine. I
would suggest that most ANSI compilers these days (I'm using gcc)
handle bitfields in the appropriate manner.


I agree with the "appropriate handling", but not with "bit fields
unless porting".

I would use bit fields only if all of the following three assumptions
are true:

(a) It does not matter what bits are assigned to which field. [1]
(b) The size of the structure containing the bit fields is not
important. [2]
(c) The alignment of a bit field structure is not important. [3]


*or*

The compiler precisely documents how it lays out bit fields, and I
know I'll never need to worry about portability to any other compiler
that doesn't make the same guarantees. Yes, masks and shifts will do
the same job, but bit fields are easier to work with.

(A good argument can be made that masks and shifts are a better idea
even in these circumstances.)
--
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.
Jun 14 '06 #16

P: n/a
>Roberto Waltman wrote:
struct com_ctrl
{
unsigned int e:1; /* enable and rate. using one letter */
unsigned int r:2; /* identifiers to fit in the */
}; /* diagrams below */
could be mapped into [various pictures, snipped]

In article <4f*************@individual.net>
Ian Collins <ia******@hotmail.com> wrote:But is it?


I have written drivers for two particular chips (one AMD Ethernet
chip and one Zilog serial port chip) that have been used on MIPS
("both endian" and one of them had only 32-bit load/store), SPARC,
Intel, and other CPUs. These drivers did not use bitfields,
despite their apparent convenience, because those bitfields were
in fact mapped differently on those different machines.

In general, using bitfields buys you a little convenience, which
you later pay for in effort porting the driver to new compilers
and machines. Sometimes this tradeoff is worth it and sometimes
it is not.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Jun 15 '06 #17

P: n/a
Keith Thompson wrote:
Roberto Waltman <us****@rwaltman.net> writes:
ri*******@latter.demon.co.uk wrote:
My main query was if there were any benefits to
bit shifting rather than defining bit fields. I think my conclusion is
that unless you are porting code, defining bitfields are fine. I
would suggest that most ANSI compilers these days (I'm using gcc)
handle bitfields in the appropriate manner.


I agree with the "appropriate handling", but not with "bit fields
unless porting".

I would use bit fields only if all of the following three assumptions
are true:

(a) It does not matter what bits are assigned to which field. [1]
(b) The size of the structure containing the bit fields is not
important. [2]
(c) The alignment of a bit field structure is not important. [3]

*or*

The compiler precisely documents how it lays out bit fields, and I
know I'll never need to worry about portability to any other compiler
that doesn't make the same guarantees. Yes, masks and shifts will do
the same job, but bit fields are easier to work with.

That's been my situation, embedded targets where the toolchain is very
unlikely to change.

--
Ian Collins.
Jun 15 '06 #18

P: n/a
Ian Collins <ia******@hotmail.com> wrote:
Keith Thompson wrote:
...
The compiler precisely documents how it lays out bit fields, and I
know I'll never need to worry about portability to any other compiler
that doesn't make the same guarantees. Yes, masks and shifts will do
the same job, but bit fields are easier to work with.

That's been my situation, embedded targets where the toolchain is very
unlikely to change.


OK, I get it now. I agree, the toolchain used for an embedded project
is not likely to change. My comments were in the context of code that
may be ported to different platforms. (Or, for communication
protocols, shared among different platforms.)
Jun 15 '06 #19

This discussion thread is closed

Replies have been disabled for this discussion.