473,324 Members | 2,214 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,324 software developers and data experts.

Bitmask vs bitfields

Hi,

This question seems to come up quite often, however I haven't managed
to find an answer relevant to my case.

I often use binary flags, and I have alaways used a "bitmask"
technique, that is using #defined or const int powers of two, and
using the following primitives :
/* declaration and initizalisation of flags */ int flags = 0;
/* setting flag */ flags |= FLAG_1;
/* resseting flag */ flags &= ~FLAG_2;
/* conditional setting or resetting */ if (condition) flags |= FLAG_3;
else flags &= ~FLAG_3;
/* testing flags */ if ((flags & FLAG_4) || !(flags & FLAG_5)) { ... }
/* copy of the flag set */ other_flags = flags;

These are the only operations I ever use, they are only internal
representations. When I store or load or exchange data, I use a human-
readable text format, which basically boils down to setting or testing
flags with the above primitives.

I recently came across the "bitfield" concept, so an alernate solution
would be:
/* declaration and initizalisation of flags */
struct {
unsigned flag1 : 1;
unsigned flag2 : 1;
unsigned flag3 : 1;
unsigned flag4 : 1;
unsigned flag5 : 1;
} flags;
/* setting flag */ flags.flag1 = 1;
/* resetting flag */ flags.flag2 = 0;
/* condition setting or resetting */ flags.flag3 = (condition);
/* testing flags */ if (flags.flag4 || !flags.flag5) { ... }
/* copy fo the flag set */ other_flags = flags;

My first question is, is the last line correct? structure assignment
is a new concept for me, and I'm not familiar with it.

Are these codes portable? I have read quite a lot of portability
warning when using bitfields, however considering the limited set of
operations I used (in particular, the internal representation of the
bitfield is never taken into accoutn), I can't see any problem in it.

Is there any efficiency difference between the two methods? Of course,
it depends on the platform and the compiler, but there might be a rule
of thumb. I have read that the bitfield is usually less efficient,
however I can't see while a compiler with optimization turned on would
produce a different code than with the bitmask method.

With my naive point of view, I can see a few advantages to the
bitfield method : I find the code much more readable (especially for
testing), there is no namespace problems, and I don't have to care
whether or not I'm using more bits than the machine word or not (I
already had to use 34 flags on a 32-bits platform with 32-bits int and
long, and it was quite painful) so in that sense it seems more
portable than the bitmask method.

Could you please help me choosing between the two methods?

Thanks in advance.
Jun 27 '08 #1
10 8442
li********@gmail.com wrote:
/* copy fo the flag set */ other_flags = flags;

My first question is, is the last line correct? structure assignment
is a new concept for me, and I'm not familiar with it.
Yes, structures are copied byte for byte.
Are these codes portable? I have read quite a lot of portability
warning when using bitfields, however considering the limited set of
operations I used (in particular, the internal representation of the
bitfield is never taken into accoutn), I can't see any problem in it.
Strictly, no. But in practice I have never had a problem using them.
Is there any efficiency difference between the two methods? Of course,
it depends on the platform and the compiler, but there might be a rule
of thumb. I have read that the bitfield is usually less efficient,
however I can't see while a compiler with optimization turned on would
produce a different code than with the bitmask method.
That you will have to measure on your platform.
With my naive point of view, I can see a few advantages to the
bitfield method : I find the code much more readable (especially for
testing), there is no namespace problems, and I don't have to care
whether or not I'm using more bits than the machine word or not (I
already had to use 34 flags on a 32-bits platform with 32-bits int and
long, and it was quite painful) so in that sense it seems more
portable than the bitmask method.

Could you please help me choosing between the two methods?
It's down to you and your requirements. I prefer bitfields for the
reasons you mention.

--
Ian Collins.
Jun 27 '08 #2
li********@gmail.com writes:
I often use binary flags, and I have alaways used a "bitmask"
technique, that is using #defined or const int powers of two, and
using the following primitives :
/* declaration and initizalisation of flags */ int flags = 0;
/* setting flag */ flags |= FLAG_1;
/* resseting flag */ flags &= ~FLAG_2;
/* conditional setting or resetting */ if (condition) flags |= FLAG_3;
else flags &= ~FLAG_3;
/* testing flags */ if ((flags & FLAG_4) || !(flags & FLAG_5)) { ... }
/* copy of the flag set */ other_flags = flags;

These are the only operations I ever use, they are only internal
representations. When I store or load or exchange data, I use a human-
readable text format, which basically boils down to setting or testing
flags with the above primitives.

I recently came across the "bitfield" concept, so an alernate solution
would be:
/* declaration and initizalisation of flags */
struct {
unsigned flag1 : 1;
unsigned flag2 : 1;
unsigned flag3 : 1;
unsigned flag4 : 1;
unsigned flag5 : 1;
} flags;
/* setting flag */ flags.flag1 = 1;
/* resetting flag */ flags.flag2 = 0;
/* condition setting or resetting */ flags.flag3 = (condition);
/* testing flags */ if (flags.flag4 || !flags.flag5) { ... }
/* copy fo the flag set */ other_flags = flags;

My first question is, is the last line correct? structure assignment
is a new concept for me, and I'm not familiar with it.
Yes, it is fine, but you need have named your struct or you won't be
able to declare the other_flags variable.
Are these codes portable? I have read quite a lot of portability
warning when using bitfields, however considering the limited set of
operations I used (in particular, the internal representation of the
bitfield is never taken into accoutn), I can't see any problem in
it.
Yes. Portability is affected by things like the largest bitfield that
is allowed, and the mapping onto values actual bit positions. You
case is OK.
Is there any efficiency difference between the two methods? Of course,
it depends on the platform and the compiler, but there might be a rule
of thumb. I have read that the bitfield is usually less efficient,
however I can't see while a compiler with optimization turned on would
produce a different code than with the bitmask method.
Do you care about such fine differences? If you do, the only recourse
is to measure and see.
With my naive point of view, I can see a few advantages to the
bitfield method : I find the code much more readable (especially for
testing), there is no namespace problems, and I don't have to care
whether or not I'm using more bits than the machine word or not (I
already had to use 34 flags on a 32-bits platform with 32-bits int and
long, and it was quite painful) so in that sense it seems more
portable than the bitmask method.

Could you please help me choosing between the two methods?
The main disadvantage (that I can see) is that bits can't be tested
in sets. If you are happy to abandon that usage, then you must also
ask why you don't just have a struct with char fields. This has a few
(slight) advantages over using bit fields and it is unlikely that
the wasted space matters except where the program needs lots of copies
of the struct.

--
Ben.
Jun 27 '08 #3
Ben Bacarisse wrote:
>
The main disadvantage (that I can see) is that bits can't be tested
in sets. If you are happy to abandon that usage, then you must also
ask why you don't just have a struct with char fields. This has a few
(slight) advantages over using bit fields and it is unlikely that
the wasted space matters except where the program needs lots of copies
of the struct.
Or the bits map to hardware.

--
Ian Collins.
Jun 27 '08 #4
Ian Collins wrote:
Ben Bacarisse wrote:
>The main disadvantage (that I can see) is that bits can't be tested
in sets. If you are happy to abandon that usage, then you must also
ask why you don't just have a struct with char fields. This has a few
(slight) advantages over using bit fields and it is unlikely that
the wasted space matters except where the program needs lots of copies
of the struct.
Or the bits map to hardware.
Or bits in some other externally defined object.

--
Ian Collins.
Jun 27 '08 #5
On Apr 17, 10:55 am, Ben Bacarisse <ben.use...@bsb.me.ukwrote:
lithium...@gmail.com writes:
Is there any efficiency difference between the two methods? Of course,
it depends on the platform and the compiler, but there might be a rule
of thumb. I have read that the bitfield is usually less efficient,
however I can't see while a compiler with optimization turned on would
produce a different code than with the bitmask method.

Do you care about such fine differences? If you do, the only recourse
is to measure and see.
I don't care about fine differences, when speed is really an issue
portability is no longer a concern and I measure to get the optimal
code
for the concerned platform.

However I do care about large differences. For example something like
"generally bitfield are vastly less effeciently implemented than
bitmask
because so few people use them" would have been enough to make me
reconsider the use of bitfields. I'm glad this is not the case.
Could you please help me choosing between the two methods?

The main disadvantage (that I can see) is that bits can't be tested
in sets. If you are happy to abandon that usage, then you must also
ask why you don't just have a struct with char fields. This has a few
(slight) advantages over using bit fields and it is unlikely that
the wasted space matters except where the program needs lots of copies
of the struct.
I've seldom needed to test a set of flags, and when it was the case it
was never more than two or three flags, so I don't mind abandonning
that.

I haven't thought about a struct of char fields, because I still can't
see the advantages over a bitfield, except the small speed gain of not
having to perform bit shifts under the scenes. Actually that might be
more efficient than the bitmask method too, I should keep that in mind
next time I have a speed-critical program. But is there any other
advantage?
Jun 27 '08 #6
Ian Collins <ia******@hotmail.comwrites:
Ian Collins wrote:
>Ben Bacarisse wrote:
>>The main disadvantage (that I can see) is that bits can't be tested
in sets. If you are happy to abandon that usage, then you must also
ask why you don't just have a struct with char fields. This has a few
(slight) advantages over using bit fields and it is unlikely that
the wasted space matters except where the program needs lots of copies
of the struct.
Or the bits map to hardware.
Or bits in some other externally defined object.
Yes, may pedant hat must have fallen off. I meant "if you are happy
to abandon the idea of bits".

--
Ben.
Jun 27 '08 #7
li********@gmail.com writes:
On Apr 17, 10:55 am, Ben Bacarisse <ben.use...@bsb.me.ukwrote:
>lithium...@gmail.com writes:
<snip>
>The main disadvantage (that I can see) is that bits can't be tested
in sets. If you are happy to abandon that usage, then you must also
ask why you don't just have a struct with char fields. This has a few
(slight) advantages over using bit fields and it is unlikely that
the wasted space matters except where the program needs lots of copies
of the struct.

I've seldom needed to test a set of flags, and when it was the case it
was never more than two or three flags, so I don't mind abandonning
that.

I haven't thought about a struct of char fields, because I still can't
see the advantages over a bitfield, except the small speed gain of not
having to perform bit shifts under the scenes. Actually that might be
more efficient than the bitmask method too, I should keep that in mind
next time I have a speed-critical program. But is there any other
advantage?
In "the old days" some compilers did support bit fields, but I can't
image there are any like that left. There will be a few situations
where writing and then reading back a struct full of chars will be
portable where a struct of bitfields is not (not many, but a few).

--
Ben.
Jun 27 '08 #8
Ian Collins wrote:
li********@gmail.com wrote:
>/* copy fo the flag set */ other_flags = flags;

My first question is, is the last line correct? structure assignment
is a new concept for me, and I'm not familiar with it.
Yes, structures are copied byte for byte.
Nitpick: What happens to padding bytes (or, in the case
of bit-fields, padding bits) is unspecified.
>Are these codes portable? I have read quite a lot of portability
warning when using bitfields, however considering the limited set of
operations I used (in particular, the internal representation of the
bitfield is never taken into accoutn), I can't see any problem in it.
Strictly, no. But in practice I have never had a problem using them.
Why "no?" Bit-fields are part of the language, the width
specified (1 bit) is supported on all implementations, and even
the implementation's discretion to make plain-int bit-fields
either signed or unsigned has been explicitly overridden with
the `unsigned' keyword. What's non-portable?

--
Eric Sosman
es*****@ieee-dot-org.invalid
Jun 27 '08 #9
li********@gmail.com wrote:
...
I recently came across the "bitfield" concept, so an alernate solution
would be:
/* declaration and initizalisation of flags */
struct {
unsigned flag1 : 1;
unsigned flag2 : 1;
unsigned flag3 : 1;
unsigned flag4 : 1;
unsigned flag5 : 1;
} flags;
/* setting flag */ flags.flag1 = 1;
/* resetting flag */ flags.flag2 = 0;
/* condition setting or resetting */ flags.flag3 = (condition);
/* testing flags */ if (flags.flag4 || !flags.flag5) { ... }
/* copy fo the flag set */ other_flags = flags;

My first question is, is the last line correct? structure assignment
is a new concept for me, and I'm not familiar with it.
Yes, it is correct.
Are these codes portable?
Yes. As long as you are only interested in the above functionality of
setting/resetting/testing flags. But once it becomes important to also guarantee
some pre-determined allocation layout if these flags in memory, the portability
ends.
Is there any efficiency difference between the two methods? Of course,
it depends on the platform and the compiler, but there might be a rule
of thumb. I have read that the bitfield is usually less efficient,
however I can't see while a compiler with optimization turned on would
produce a different code than with the bitmask method.
Well, as you said it yourself, it depends on the compiler. Sometimes even good
optimizing compilers miss rather "obvious" optimization opportunities.
With my naive point of view, I can see a few advantages to the
bitfield method : I find the code much more readable (especially for
testing), there is no namespace problems, and I don't have to care
whether or not I'm using more bits than the machine word or not (I
already had to use 34 flags on a 32-bits platform with 32-bits int and
long, and it was quite painful) so in that sense it seems more
portable than the bitmask method.
It is easier to get carried away with bit fields, lose track of how much memory
you are actually trying to occupy and inadvertently cause data memory bloat.

--
Best regards,
Andrey Tarasevich
Jun 27 '08 #10
Ben Bacarisse wrote:
...
The main disadvantage (that I can see) is that bits can't be tested
in sets. If you are happy to abandon that usage,
...
Well, bitfields _can_ be tested in sets. Except that in case of bitfield the set
has to be described by a expression in the program source code, as in

if (flags.flag1 && flags.flag2 && !flags.flag3)

and that is indeed a problem. With "manually" implemented bitfields this test
can be described by a pair of run-time values (a test mask and an expected
value), while with language-supported bitfields this is impossible to achieve.
In general, this is an important difference, I'd say.

--
Best regards,
Andrey Tarasevich
Jun 27 '08 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: tmartsum | last post by:
I have a discussion in comp.std.c++ After a (bit stupid) suggestion on representing a fixed 'big' length int I moderated it to "Bitfields-ints should be allowed to have any fixed length" I...
8
by: Régis Troadec | last post by:
Hi all, I follow c.l.c. for only a short time and I would like to know why there isn't anything concerning bitfields among the FAQs. Is it because ... 1. of portability issues? 2. bitfields...
23
by: rohit | last post by:
Hi, In my couple of years of experience, I have never found a single instance where I needed to use unions and bitfields(though I have used structures).I was just imagining where would these find...
6
by: GalenTX | last post by:
I am looking for opinions on a possible approach to coping with bitfields in a heterogenous environment. We've got a bunch of legacy code which maps to hardware using bitfields. The code was...
19
by: Mehta Shailendrakumar | last post by:
Hi, I would like to know why array of bitfields is not possible. Is there any relation with processor architecture for this? Thank you for your time. Regards, Shailendra
5
by: Andy | last post by:
Sigh... working on it for whole day and got no idea... Basically I want to have a bitmask filtering function, I will throw in 3 parameters: bitMaskValue - current bitmask value filterValue -...
18
by: richard_l | last post by:
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...
9
by: cman | last post by:
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...
3
by: TD | last post by:
Is there a way to DataBind controls to a specific Bit in Bitmask? Here is some sample code of what I am trying to do ... I am trying to bind the Visible and Enabled properties of a Button to...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.