Bitmask vs bitfields

Discussion in 'C Programming' started by lithiumcat@gmail.com, Apr 17, 2008.

  1. Guest

    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.
     
    , Apr 17, 2008
    #1
    1. Advertising

  2. Ian Collins Guest

    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.
     
    Ian Collins, Apr 17, 2008
    #2
    1. Advertising

  3. 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.
     
    Ben Bacarisse, Apr 17, 2008
    #3
  4. Ian Collins Guest

    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.
     
    Ian Collins, Apr 17, 2008
    #4
  5. Ian Collins Guest

    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.
     
    Ian Collins, Apr 17, 2008
    #5
  6. Guest

    On Apr 17, 10:55 am, Ben Bacarisse <> wrote:
    > 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?
     
    , Apr 17, 2008
    #6
  7. Ian Collins <> writes:

    > 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.
     
    Ben Bacarisse, Apr 17, 2008
    #7
  8. writes:

    > On Apr 17, 10:55 am, Ben Bacarisse <> wrote:
    >> 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.
     
    Ben Bacarisse, Apr 17, 2008
    #8
  9. Ian Collins Guest

    Eric Sosman wrote:
    > Ian Collins wrote:
    >> wrote:

    >
    >>> 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?
    >

    I thought the order of the bits and support for bigger than unsigned
    char sized fields was implementation defined.

    --
    Ian Collins.
     
    Ian Collins, Apr 17, 2008
    #9
  10. Ian Collins Guest

    Eric Sosman wrote:
    > Ian Collins wrote:
    >> Eric Sosman wrote:


    >>> What's non-portable?
    >>>

    >> I thought the order of the bits and support for bigger than unsigned
    >> char sized fields was implementation defined.

    >
    > The arrangement of the bits in the "storage unit" is
    > implementation-defined, as is the size of the S.U. itself.
    > But that doesn't matter if you're treating the bit-fields
    > individually (as the O.P. was); it's only an issue if you're
    > trying to manipulate them en masse or make them match an
    > externally-imposed format or something of that kind.
    >

    That was my point. Other's experience may differ, but most of my uses
    of bit-fields have been in drivers to map registers and protocols to map
    bits in packets.

    --
    Ian Collins.
     
    Ian Collins, Apr 17, 2008
    #10
  11. Guest

    Ian Collins <> wrote:
    >
    > I thought the order of the bits and support for bigger than unsigned
    > char sized fields was implementation defined.


    The order of the bits is, but implementations must support bit fields up
    to the width of an object with the same type as the bit field, so int
    bit fields up to 15 bits are portable as are unsigned bit fields up to
    16 bits.

    -Larry Jones

    At times like these, all Mom can think of is how long she was in
    labor with me. -- Calvin
     
    , Apr 17, 2008
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Rod Nibbe

    Bitmask & Graphics Question

    Rod Nibbe, Oct 26, 2004, in forum: Java
    Replies:
    2
    Views:
    1,663
    Rod Nibbe
    Oct 26, 2004
  2. Andrey Brozhko
    Replies:
    1
    Views:
    1,151
    Andrey Brozhko
    Dec 10, 2004
  3. =?iso-8859-9?Q?Tongu=E7?= Yumruk

    Bitmask representation of integers

    =?iso-8859-9?Q?Tongu=E7?= Yumruk, Oct 8, 2003, in forum: Python
    Replies:
    3
    Views:
    918
    Scott David Daniels
    Oct 8, 2003
  4. Xah Lee
    Replies:
    0
    Views:
    370
    Xah Lee
    Apr 23, 2007
  5. Andrew Shepson

    Bitmask vs bitfields

    Andrew Shepson, Jun 3, 2010, in forum: C Programming
    Replies:
    6
    Views:
    2,792
    ImpalerCore
    Jun 4, 2010
Loading...

Share This Page