Bitfield structs that are not padded to the size of an int?

Discussion in 'C Programming' started by Davide Bruzzone, Aug 15, 2003.

  1. Greetings all...

    I need to create a number of bitfield structs whose contents are
    smaller than the size of an int. For example:

    typedef struct foo FOO;

    struct foo {
    unsigned char fieldOne: 2, fieldTwo: 6;
    };

    I'd like this struct to take up no more than 8 bits, however, when I
    call sizeof(FOO), the function returns 4 bytes (which is the size of
    an int on the platform on which I'm compiling my code).

    Now I know that according to the ANSI C standard, this is normal (i.e.
    Bitfield structs are padded to the size of an int). What I'm having
    trouble finding more/clearer information about is:

    - Whether its possible to force the compiler to bend/break this rule,
    and to create non-padded bitfield structs that take us, say, one byte
    or two (BTW, I'm using GCC 2.95.1).
    - If this is possible, how I go about doing it (i.e. What command-line
    options I need to use, and what, if anything, I need to add to my
    code).

    Any suggestions, or pointers to the appropriate information would be
    greatly appreciated.

    Cheers...

    Dave Bruzzone
     
    Davide Bruzzone, Aug 15, 2003
    #1
    1. Advertising

  2. Davide Bruzzone

    Derk Gwen Guest

    # - Whether its possible to force the compiler to bend/break this rule,
    # and to create non-padded bitfield structs that take us, say, one byte
    # or two (BTW, I'm using GCC 2.95.1).

    Or just use a byte, and do the field extractions and insertions yourself.

    --
    Derk Gwen http://derkgwen.250free.com/html/index.html
    What kind of convenience store do you run here?
     
    Derk Gwen, Aug 15, 2003
    #2
    1. Advertising

  3. Derk Gwen <> wrote in message news:<>...
    > # - Whether its possible to force the compiler to bend/break this rule,
    > # and to create non-padded bitfield structs that take us, say, one byte
    > # or two (BTW, I'm using GCC 2.95.1).
    >
    > Or just use a byte, and do the field extractions and insertions yourself.


    Having thought further about the problem, I suppose that a better way
    to have asked the question would probably have been:

    I have a stream of bytes (or characters) from which I need to extract
    information. Since the individual bytes within the stream may use "bit
    fields" within those bytes to represent specific pieces of
    information, I thought that I might create a struct into which I could
    copy the stream of bytes. I don't know whether this is possible, and
    if it is, whether or not this is a dumb way to do it.

    So, I suppose that my question should have been:

    Given a stream of bytes:

    Byte
    0 1 etc.
    Bit
    1234567812345678...

    aabbccccdddddddd...

    Where aa represents a specific piece of information, bb represents
    another piece of information, cccc yet another piece of information,
    and so on...

    What is the best way to read this stream of bytes and extract all
    these pieces of information from it? Should I just read the stream
    into a big buffer and use bit masks?

    Thank you for your initial suggestion...

    Cheers...

    Dave Bruzzone
     
    Davide Bruzzone, Aug 15, 2003
    #3
  4. > > - If this is possible, how I go about doing it (i.e. What command-line
    > > options I need to use, and what, if anything, I need to add to my
    > > code).

    >
    > Try a gcc newsgroup since this is really a compiler question at this
    > point.


    Doh! Thanks for the suggestion Mark...

    Cheers...

    Dave Bruzzone
     
    Davide Bruzzone, Aug 15, 2003
    #4
  5. Davide Bruzzone

    Eric Sosman Guest

    Davide Bruzzone wrote:
    >
    > Derk Gwen <> wrote in message news:<>...
    > > # - Whether its possible to force the compiler to bend/break this rule,
    > > # and to create non-padded bitfield structs that take us, say, one byte
    > > # or two (BTW, I'm using GCC 2.95.1).
    > >
    > > Or just use a byte, and do the field extractions and insertions yourself.

    >
    > Having thought further about the problem, I suppose that a better way
    > to have asked the question would probably have been:
    >
    > I have a stream of bytes (or characters) from which I need to extract
    > information. Since the individual bytes within the stream may use "bit
    > fields" within those bytes to represent specific pieces of
    > information, I thought that I might create a struct into which I could
    > copy the stream of bytes. I don't know whether this is possible, and
    > if it is, whether or not this is a dumb way to do it.


    Bit fields *look* like a way to do this, but as you've
    discovered they're really not up to the job. (Similarly,
    structs *look* like a way to match externally-defined data
    formats, but they're not quite capable of it.)

    > So, I suppose that my question should have been:
    >
    > Given a stream of bytes:
    >
    > Byte
    > 0 1 etc.
    > Bit
    > 1234567812345678...
    >
    > aabbccccdddddddd...


    It is more usual to number the bits from 0 to 7 (or
    from 0 to N; see below), from least- to most-significant.
    That way, the number of each bit is the same as the power
    of two that it represents, and this has mnemonic value.

    > Where aa represents a specific piece of information, bb represents
    > another piece of information, cccc yet another piece of information,
    > and so on...
    >
    > What is the best way to read this stream of bytes and extract all
    > these pieces of information from it? Should I just read the stream
    > into a big buffer and use bit masks?


    That's the most portable approach. Note that I wrote
    "most," not "completely," because C doesn't require that a
    byte be only 8 bits wide ... Most general purpose computers
    today use 8-bit bytes, but machines with 32-bit bytes are
    found in some arenas. Other widths are certainly possible
    and have been used, but 9-bit bytes are today mostly a fading
    memory.

    Your job will be simplified if you happen to know that
    the fields of interest are always entirely contained within
    single bytes. Assuming an 8-bit byte, your example could be
    decoded this way:

    unsigned char b0, b1;
    int aa = b0 >> 6;
    int bb = (b0 >> 4) & 0x3;
    int cccc = b0 & 0xF;
    int dddddddd = b1;

    If fields sprawl across byte boundaries things get messier,
    but not irretrievably so. The approach is to extract the
    sub-fields from different bytes and then to piece them together.
    If in your example there were eight c's and four d's instead
    of the other way around, it could be decoded thus:

    unsigned char b0, b1;
    int aa = b0 >> 6;
    int bb = (b0 >> 4) & 0x3;
    int cccccccc = ((b0 & 0xF) << 4) | (b1 >> 4);
    int dddd = b1 & 0xF;

    --
     
    Eric Sosman, Aug 15, 2003
    #5
  6. Davide Bruzzone wrote:
    > Greetings all...
    >
    > I need to create a number of bitfield structs whose contents are
    > smaller than the size of an int. For example:
    >
    > typedef struct foo FOO;
    >
    > struct foo {
    > unsigned char fieldOne: 2, fieldTwo: 6;
    > };
    >
    > I'd like this struct to take up no more than 8 bits, however, when I
    > call sizeof(FOO), the function returns 4 bytes (which is the size of
    > an int on the platform on which I'm compiling my code).


    Then don't use bitfields. If CHAR_BIT==8 on your machine, just use
    unsigned chars and normal bitwise operators. If CHAR_BIT > 8 on your
    machine, then you can't (in C) do what you want.


    --
    Martin Ambuhl
     
    Martin Ambuhl, Aug 15, 2003
    #6
  7. On Fri, 15 Aug 2003 17:49:05 UTC, (Davide
    Bruzzone) wrote:

    > Derk Gwen <> wrote in message news:<>...
    > > # - Whether its possible to force the compiler to bend/break this rule,
    > > # and to create non-padded bitfield structs that take us, say, one byte
    > > # or two (BTW, I'm using GCC 2.95.1).
    > >
    > > Or just use a byte, and do the field extractions and insertions yourself.

    >
    > Having thought further about the problem, I suppose that a better way
    > to have asked the question would probably have been:
    >
    > I have a stream of bytes (or characters) from which I need to extract
    > information. Since the individual bytes within the stream may use "bit
    > fields" within those bytes to represent specific pieces of
    > information, I thought that I might create a struct into which I could
    > copy the stream of bytes. I don't know whether this is possible, and
    > if it is, whether or not this is a dumb way to do it.
    >
    > So, I suppose that my question should have been:
    >
    > Given a stream of bytes:
    >
    > Byte
    > 0 1 etc.
    > Bit
    > 1234567812345678...
    >
    > aabbccccdddddddd...
    >
    > Where aa represents a specific piece of information, bb represents
    > another piece of information, cccc yet another piece of information,
    > and so on...
    >
    > What is the best way to read this stream of bytes and extract all
    > these pieces of information from it? Should I just read the stream
    > into a big buffer and use bit masks?
    >
    > Thank you for your initial suggestion...


    You've 2 choices:
    1. implementation defined:

    union c {
    struct bits {
    unsigned char a :2;
    unsigned char b :2;
    unsigned char c ....
    } bits;
    char chr;
    }uc;

    copy one char in c.char and read the bits. It's critical because
    you can't port the program between different implementations (may
    be not even between different versions of the same implementation).

    uc.chr = readed_char;

    2. standard compilant:

    Fiddle out the bits of each char by hand and set them.

    c = (readed_char & 0xc0) >> NUMBER_OF_BIT_SHIFT_a;
    bits.a = c;
    c = readed_char & 0x30 ..........

    work with the bits by name....

    write_char = (bits.a & 0x03) << NUMBER_OF_BIT_SHIFT_a;
    write_char |= ......

    If you needs a compact form you will be implementation defined because
    you needs an implementation defined #pragma to push away the natural
    alignment the implementation uses to pack data members of a
    struct/union to its minimal size:

    #pragma align(1)
    union c c_arr[4711];
    #pragma align()

    In that case you can simply use the array directly to read/write the
    stream. But you has to recheck your solution when the version of your
    implementation changes.

    When you needs to be standard conform you have no chance to build an
    array in packed form.

    --
    Tschau/Bye

    Herbert Rosenau
    http://www.pc-rosenau.de eComStation Reseller in Germany
    eCS 1.1 german is in beta testing
     
    The real OS2 guy, Aug 16, 2003
    #7
  8. On Fri, 15 Aug 2003 19:25:36 UTC, CBFalconer <>
    wrote:

    > Davide Bruzzone wrote:
    > >
    > > I need to create a number of bitfield structs whose contents are
    > > smaller than the size of an int. For example:
    > >
    > > typedef struct foo FOO;
    > >
    > > struct foo {
    > > unsigned char fieldOne: 2, fieldTwo: 6;
    > > };
    > >
    > > I'd like this struct to take up no more than 8 bits, however, when I
    > > call sizeof(FOO), the function returns 4 bytes (which is the size of
    > > an int on the platform on which I'm compiling my code).

    >
    > Don't use bitfields.


    Why not? The only you needs is an clearly defined interface to
    (un)serialise the bitstream. No macro can make the code really
    readable, but a bit structure makes it. You needs the macros you
    describes in the serialiser functions, but you can access the bits in
    the whole application by theyr names.

    Use an unsigned char and masks. You can
    > make the access clearer with a few macros:
    >
    > #define getFLDone(x) (x & 0x3)
    > #define getFLDtwo(x) ((x & 0xfc) >> 2)
    >
    > #define setFLDone(x, val) ((x & 0xfc) | (val & 0x3))
    > #define setFLDtwo(x, val) ((x & 0x3) | (val << 2))
    >
    > all untested. Now I suspect you can write:
    >
    > unsigned char storage, another;
    > ...
    > whatever = getFLDone(storage);
    > another = setFLDtwo(storage, whatever);
    >


    Make a clean design of the app and you non't need to fiddle around
    with binary operators and shift operations in the app, because the
    compiler can do this under cover for you. The only you needs is an
    interface to the external storage that produces both, bytes to
    bitfields and back. Even as the interface itself is only
    implementation defined your app can be standard compilant.

    In every bigger project you have a little part that is implementation
    defined. Now you've a bit more to make the bitfields independant, but
    that it's.

    --
    Tschau/Bye

    Herbert Rosenau
    http://www.pc-rosenau.de eComStation Reseller in Germany
    eCS 1.1 german is in beta testing
     
    The real OS2 guy, Aug 16, 2003
    #8
  9. To all who have responded...

    Thnks again for all your responses. They've all be very useful and enlightening.

    Cheers...

    Dave
     
    Davide Bruzzone, Aug 16, 2003
    #9
  10. Davide Bruzzone

    Adam S. Roan Guest

    You can only use bit fields on words. And manipulate words using bit-fields.

    --bloodeu


    "Davide Bruzzone" <> wrote in message
    news:...
    > Greetings all...
    >
    > I need to create a number of bitfield structs whose contents are
    > smaller than the size of an int. For example:
    >
    > typedef struct foo FOO;
    >
    > struct foo {
    > unsigned char fieldOne: 2, fieldTwo: 6;
    > };
    >
    > I'd like this struct to take up no more than 8 bits, however, when I
    > call sizeof(FOO), the function returns 4 bytes (which is the size of
    > an int on the platform on which I'm compiling my code).
    >
    > Now I know that according to the ANSI C standard, this is normal (i.e.
    > Bitfield structs are padded to the size of an int). What I'm having
    > trouble finding more/clearer information about is:
    >
    > - Whether its possible to force the compiler to bend/break this rule,
    > and to create non-padded bitfield structs that take us, say, one byte
    > or two (BTW, I'm using GCC 2.95.1).
    > - If this is possible, how I go about doing it (i.e. What command-line
    > options I need to use, and what, if anything, I need to add to my
    > code).
    >
    > Any suggestions, or pointers to the appropriate information would be
    > greatly appreciated.
    >
    > Cheers...
    >
    > Dave Bruzzone
     
    Adam S. Roan, Aug 27, 2003
    #10
    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. Schnoffos
    Replies:
    2
    Views:
    1,252
    Martien Verbruggen
    Jun 27, 2003
  2. Hal Styli
    Replies:
    14
    Views:
    1,713
    Old Wolf
    Jan 20, 2004
  3. Andy Venikov

    bitfield size check

    Andy Venikov, Jun 22, 2004, in forum: C Programming
    Replies:
    3
    Views:
    789
  4. Replies:
    6
    Views:
    481
    John Machin
    Mar 17, 2005
  5. nass
    Replies:
    3
    Views:
    300
    Pete Becker
    Feb 13, 2007
Loading...

Share This Page