bitfield size check

Discussion in 'C Programming' started by Andy Venikov, Jun 22, 2004.

  1. Andy Venikov

    Andy Venikov Guest

    Sometimes you want to use a bitfield to hold an enum value. In such
    cases you would only use as many bits as are needed to encode the
    full set of enum values. And it is a pain to recompute and updated
    the bitfield length each time you add new enum values. But there is
    a way to make the compiler do it for you. Like this:

    enum Enums
    {
    Enum1,
    Enum2,
    Enum3,
    Enum4,

    TotalEnums,
    };

    struct A
    {
    Enums enumValue:COMPUTE_BITFIELD_LENGTH(TotalEnums);
    };

    And COMPUTE_BITFIELD_LENGTH would look something like this:

    #define COMPUTE_BITFIELD_LENGTH(n) ((n) < 1) ? 0 : ((n) < 3) ? 1 :\
    ((n) < 5) ? 2 : ((n) < 9) ? 3 : ((n) < 17) ? 4 : ((n) < 33) ? 5 :\
    ((n) < 65) ? 6 : ((n) < 129) ? 7 : ((n) < 257) ? 8 : 32


    It works fine.
    Unless the number Enums is exactly the power of 2, in wich case
    some compilers give warning akin to this:
    "A::enumValue is too small to hold all values of Enums" appears.
    It happens because the compiler considers TotalEnums to be part of the
    enum set in wich case the total number of values become power of 2 plus
    one and you need one additional bit.

    Is there a way to compute the size of the enum structure
    without introducing a new enum value?

    Thanks,
    Andy.
    Andy Venikov, Jun 22, 2004
    #1
    1. Advertising

  2. Andy Venikov

    Eric Sosman Guest

    Andy Venikov wrote:
    > Sometimes you want to use a bitfield to hold an enum value. In such
    > cases you would only use as many bits as are needed to encode the
    > full set of enum values. And it is a pain to recompute and updated
    > the bitfield length each time you add new enum values. But there is
    > a way to make the compiler do it for you. Like this:
    >
    > enum Enums
    > {
    > Enum1,
    > Enum2,
    > Enum3,
    > Enum4,
    >
    > TotalEnums,


    The trailing comma is allowed in C99, but forbidden
    in C89.

    > };
    >
    > struct A
    > {
    > Enums enumValue:COMPUTE_BITFIELD_LENGTH(TotalEnums);


    I think you mean `enum Enums enumValue ...'. However,
    I think you should instead use `unsigned int enumValue ...',
    for two reasons: First, only the `int' types (and `_Bool'
    in C99) are portable "base types" for bit-fields -- the
    compiler is allowed to accept other types, but is not
    required to do so. Second, your compiler's willingness to
    accept an enum type as a bit-field base is actually making
    trouble for you -- ditch the non-portable type, and the
    trouble will probably go away.

    > };
    >
    > And COMPUTE_BITFIELD_LENGTH would look something like this:
    >
    > #define COMPUTE_BITFIELD_LENGTH(n) ((n) < 1) ? 0 : ((n) < 3) ? 1 :\
    > ((n) < 5) ? 2 : ((n) < 9) ? 3 : ((n) < 17) ? 4 : ((n) < 33) ? 5 :\
    > ((n) < 65) ? 6 : ((n) < 129) ? 7 : ((n) < 257) ? 8 : 32


    Note that since the `int' flavors are the widest portable
    bit-field base types, portable bit-fields can be no wider
    than `int'. `int' can be as narrow as sixteen bits, so a
    bit-field width of thirty-two is not portable.

    > It works fine.
    > Unless the number Enums is exactly the power of 2, in wich case
    > some compilers give warning akin to this:
    > "A::enumValue is too small to hold all values of Enums" appears.
    > It happens because the compiler considers TotalEnums to be part of the
    > enum set in wich case the total number of values become power of 2 plus
    > one and you need one additional bit.
    >
    > Is there a way to compute the size of the enum structure
    > without introducing a new enum value?


    You could instead keep track of the highest actual value:

    enum Enums { A, B, C, D };
    #define TotalEnums (D + 1)

    Of course, less "regular" enum types could make trouble:

    enum Ugly { W = -42, X = 1, Y, Z };
    #define TotalUglies (Z + 1)

    .... might fool you into thinking you need only two bits to
    store an `enum Ugly' value.

    --
    Eric Sosman, Jun 22, 2004
    #2
    1. Advertising

  3. (Andy Venikov) writes:
    > Sometimes you want to use a bitfield to hold an enum value. In such
    > cases you would only use as many bits as are needed to encode the
    > full set of enum values. And it is a pain to recompute and updated
    > the bitfield length each time you add new enum values. But there is
    > a way to make the compiler do it for you. Like this:
    >
    > enum Enums
    > {
    > Enum1,
    > Enum2,
    > Enum3,
    > Enum4,
    >
    > TotalEnums,
    > };
    >
    > struct A
    > {
    > Enums enumValue:COMPUTE_BITFIELD_LENGTH(TotalEnums);
    > };
    >
    > And COMPUTE_BITFIELD_LENGTH would look something like this:

    [snip]
    > It works fine.
    > Unless the number Enums is exactly the power of 2, in wich case
    > some compilers give warning akin to this:
    > "A::enumValue is too small to hold all values of Enums" appears.
    > It happens because the compiler considers TotalEnums to be part of the
    > enum set in wich case the total number of values become power of 2 plus
    > one and you need one additional bit.
    >
    > Is there a way to compute the size of the enum structure
    > without introducing a new enum value?


    Perhaps something like this:

    enum Enums {
    Enum1,
    Enum2,
    Enum3,
    Enum4,
    LastEnum = Enum4
    };

    Adjust your big ugly macro accordingly, and don't forget to update the
    value assigned to LastEnums if you add new values at the end.

    --
    Keith Thompson (The_Other_Keith) <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.
    Keith Thompson, Jun 23, 2004
    #3
  4. Andy Venikov

    kal Guest

    Keith Thompson <> wrote in message news:<>...
    > Perhaps something like this:
    >
    > enum Enums {
    > Enum1,
    > Enum2,
    > Enum3,
    > Enum4,
    > LastEnum = Enum4
    > };


    I like this one. But one might as well specify the number
    of bits as an enum constant if one insists on having this
    pseudo #define as part of the enum definition.

    enum ugly {low=-1, medium=0, high=1, BITS=3};

    --

    "See ma, no macro!"
    kal, Jun 23, 2004
    #4
    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. zb32

    bitfield optimizations

    zb32, Jul 13, 2004, in forum: C++
    Replies:
    1
    Views:
    1,063
    David Harmon
    Jul 13, 2004
  2. Claudio

    bitfield & union strange ?!

    Claudio, Aug 1, 2004, in forum: C++
    Replies:
    2
    Views:
    4,886
    Gottfried Eibner
    Aug 2, 2004
  3. Replies:
    0
    Views:
    521
  4. Davide Bruzzone
    Replies:
    9
    Views:
    378
    Adam S. Roan
    Aug 27, 2003
  5. nass
    Replies:
    3
    Views:
    283
    Pete Becker
    Feb 13, 2007
Loading...

Share This Page