De facto standard size of bit-field objects

Discussion in 'C Programming' started by marktxx@yahoo.com, Feb 23, 2007.

  1. Guest

    Although the C90 standard only mentions the use of 'signed int' and
    'unsigned int' for bit-fields (use 'int' at your own risk) and C99
    adds _Bool.
    It seems that most compilers create the size of the bit-field object
    from the size used to specify the field.

    Could this be considered a defacto standard now (at least for 8 bit
    sized bit-fields)?

    Any recent compilers not allowing this?

    struct
    {
    unsigned char x:4;
    unsigned char y:4;
    } nibs;


    struct
    {
    unsigned int x:4;
    unsigned int y:4;
    } nibs;

    see

    http://www.keil.com/support/docs/928.htm

    It refers the OP to the book
    "The C Programming Language" by Kernighan & Ritchie but this book
    doesn't mention using unsigned char in bit-fields.


    [Soapbox]
    Wouldn't it had more sense for the compiler folks to just add up the
    specified number bits and use the smallest integer type that would fit
    so code could follow the standard?
    Obviously programmers want to use bit-field objects that may be
    smaller or larger than standard integer size shouldn't the standard
    support that.
    (I know that one can always use masking and shifting but that isn't my
    question.)
    [end soapbox]
     
    , Feb 23, 2007
    #1
    1. Advertising

  2. writes:
    > Although the C90 standard only mentions the use of 'signed int' and
    > 'unsigned int' for bit-fields (use 'int' at your own risk) and C99
    > adds _Bool.
    > It seems that most compilers create the size of the bit-field object
    > from the size used to specify the field.


    Of course.

    > Could this be considered a defacto standard now (at least for 8 bit
    > sized bit-fields)?
    >
    > Any recent compilers not allowing this?
    >
    > struct
    > {
    > unsigned char x:4;
    > unsigned char y:4;
    > } nibs;
    >
    >
    > struct
    > {
    > unsigned int x:4;
    > unsigned int y:4;
    > } nibs;


    Oh, you meant that the *type* of the bit-field determines the size.

    > see
    >
    > http://www.keil.com/support/docs/928.htm


    Apparently for that compiler the type of a bit field affects the size
    of the enclosing structure (though it doesn't affect the size of the
    bit field itself). In the second declaration, the structure
    apparently is at least as large as unsigned int.

    C99 6.7.2.1p9:

    A bit-field is interpreted as a signed or unsigned integer type
    consisting of the specified number of bits.

    Allowing unsigned char bit fields is obviously a compiler extension.
    Making a struct bigger than it needs to be based on the declared type
    of a bit field, rather than its declared width, is an odd choice and
    is not required, or even suggested, by the standard as far as I can
    tell. (I've seen this behavior in other compilers, including gcc.)

    [...]

    > [Soapbox]
    > Wouldn't it had more sense for the compiler folks to just add up the
    > specified number bits and use the smallest integer type that would fit
    > so code could follow the standard?
    > Obviously programmers want to use bit-field objects that may be
    > smaller or larger than standard integer size shouldn't the standard
    > support that.
    > (I know that one can always use masking and shifting but that isn't my
    > question.)
    > [end soapbox]


    The width (":4" in the examples above) determines the size of a bit
    field, not the declared type. I suggest that the compiler should be
    smart enough to treat int and unsigned int bit fields properly without
    wasting space. I see no need to change the standard.

    Perhaps there's some sensible rationale for this behavior, but I'm not
    seeing it.

    --
    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, Feb 23, 2007
    #2
    1. Advertising

  3. On Fri, 23 Feb 2007 wrote:
    >
    > Although the C90 standard only mentions the use of 'signed int' and
    > 'unsigned int' for bit-fields (use 'int' at your own risk) and C99
    > adds _Bool.
    > It seems that most compilers create the size of the bit-field object
    > from the size used to specify the field.
    >
    > Could this be considered a defacto standard now (at least for 8 bit
    > sized bit-fields)?


    I don't exactly see what you mean. I think you are saying that on
    "most" compilers, the structure definition

    > struct {
    > unsigned char x:4;
    > unsigned char y:4;
    > } nibs;


    yields a struct with a size of 8 bits, arranged as xxxxyyyy, but

    > struct {
    > unsigned int x:4;
    > unsigned int y:4;
    > } nibs;


    yields a struct with a size of 32 bits, arranged as
    xxxxyyyy000000000000000000000000.

    This is indeed true for Keil's compiler:

    > http://www.keil.com/support/docs/928.htm


    and GCC and yes, probably most modern compilers. However, there's
    an extra wrinkle that you didn't mention: On "most" compilers, a
    bitfield of declared type T will never span memory chunks of
    size T. (The real type of a bitfield is simply a "bit-field type"; but
    like you, I'm talking about the "unsigned char" or whatever that you
    use in the struct definition.)
    For example, an "unsigned char" bitfield will never span two bytes;
    padding bits will be inserted if necessary to justify it in its own
    byte. Therefore, the struct definition

    struct {
    unsigned char x : 5;
    unsigned char y : 5;
    } nabs;

    will correspond on "most" compilers to xxxxx000yyyyy000, while

    struct {
    unsigned short x : 5;
    unsigned short y : 5;
    } nabs;

    will correspond to xxxxxyyyyy000000.


    > [Soapbox]
    > Wouldn't it had more sense for the compiler folks to just add up the
    > specified number bits and use the smallest integer type that would fit
    > so code could follow the standard?


    It would make about as much sense, I guess. I don't see how it would
    make /more/ sense. If you care about that kind of micro-optimization,
    you probably welcome the extra tiny bit of control over alignment given
    to you by the "de-facto" standard.
    The issue may originally have been that unaligned memory accesses are
    terribly slow on most platforms; therefore, it makes sense to allow the
    programmer to force byte-alignment or word-alignment with a minimum of
    fuss. (C99 introduced anonymous bitfields to deal with the same issue.)
    The issue now is certainly compatibility with other compilers. Peer
    pressure is a strong force in the compiler field.

    N869 section 6.7.2.1#9 seems to encourage the "de-facto" behavior:

    [#9] An implementation may allocate any addressable storage
    unit large enough to hold a bit-field. 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. 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. The
    order of allocation of bit-fields within a unit (high-order
    to low-order or low-order to high-order) is implementation-
    defined. The alignment of the addressable storage unit is
    unspecified.

    > Obviously programmers want to use bit-field objects that may be
    > smaller or larger than standard integer size shouldn't the standard
    > support that.


    No. If there's no Standard support for 128-bit integer math, it
    seems pretty silly to require implementations to support integer
    math on bitfields of type "signed int foo : 128". That would put a
    huge burden on implementors to deal with arbitrarily-wide integer
    math, while making users jump through silly hoops to get at it.

    Some compilers support "long long" bitfields. Interestingly, GCC
    will pack "long long" bitfields across 8-byte boundaries, and will pad
    them only to 4-byte boundaries (e.g., a struct containing two fields
    of type "long long : 4" will have size 32 bits, not 64 bits). That
    seems needlessly inconsistent to me, but I don't know what other
    compilers do. I'll find out what ours does on Monday. ;)

    -Arthur,
    one of those compiler folks
     
    Arthur J. O'Dwyer, Feb 24, 2007
    #3
  4. Thad Smith Guest

    Keith Thompson wrote:
    > writes:
    >>struct
    >>{
    >> unsigned char x:4;
    >> unsigned char y:4;
    >>} nibs;
    >> ...
    >>http://www.keil.com/support/docs/928.htm

    >
    > Apparently for that compiler the type of a bit field affects the size
    > of the enclosing structure (though it doesn't affect the size of the
    > bit field itself). In the second declaration, the structure
    > apparently is at least as large as unsigned int.
    > ...
    > Allowing unsigned char bit fields is obviously a compiler extension.
    > Making a struct bigger than it needs to be based on the declared type
    > of a bit field, rather than its declared width, is an odd choice and
    > is not required, or even suggested, by the standard as far as I can
    > tell. (I've seen this behavior in other compilers, including gcc.)
    > ...
    > The width (":4" in the examples above) determines the size of a bit
    > field, not the declared type. I suggest that the compiler should be
    > smart enough to treat int and unsigned int bit fields properly without
    > wasting space. I see no need to change the standard.
    >
    > Perhaps there's some sensible rationale for this behavior, but I'm not
    > seeing it.


    The rationale, I think, is to be compatible with other compilers that
    set the minimum size for a struct containing bit fields as the size of
    an int. The extension, then, provides that compatibility and allows
    generating a minimum-size struct.

    That said, I think that the int-size minimum and compatibility attempt
    are wrong-headed. I agree that compilers should use the minimum size of
    a struct unless that causes a penalty somewhere.

    --
    Thad
     
    Thad Smith, Feb 24, 2007
    #4
  5. "Arthur J. O'Dwyer" <> writes:
    [...]
    > (C99 introduced anonymous bitfields to deal with the same issue.)

    [...]

    C90 has anonymous bitfields.

    --
    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, Feb 24, 2007
    #5
  6. Guest

    On Feb 23, 11:43 pm, "Arthur J. O'Dwyer" <>
    wrote:
    > On Fri, 23 Feb 2007 wrote:
    >
    >
    >
    > > Although the C90 standard only mentions the use of 'signed int' and
    > > 'unsigned int' for bit-fields (use 'int' at your own risk) and C99
    > > adds _Bool.
    > > It seems that most compilers create the size of the bit-field object
    > > from the size used to specify the field.

    >
    > > Could this be considered a defacto standard now (at least for 8 bit
    > > sized bit-fields)?

    >
    > I don't exactly see what you mean. I think you are saying that on
    > "most" compilers, the structure definition
    >
    > > struct {
    > > unsigned char x:4;
    > > unsigned char y:4;
    > > } nibs;

    >
    > yields a struct with a size of 8 bits, arranged as xxxxyyyy, but
    >
    > > struct {
    > > unsigned int x:4;
    > > unsigned int y:4;
    > > } nibs;

    >
    > yields a struct with a size of 32 bits, arranged as
    > xxxxyyyy000000000000000000000000.
    >
    > This is indeed true for Keil's compiler:
    >
    > >http://www.keil.com/support/docs/928.htm

    >
    > and GCC and yes, probably most modern compilers. However, there's
    > an extra wrinkle that you didn't mention: On "most" compilers, a
    > bitfield of declared type T will never span memory chunks of
    > size T. (The real type of a bitfield is simply a "bit-field type"; but
    > like you, I'm talking about the "unsigned char" or whatever that you
    > use in the struct definition.)
    > For example, an "unsigned char" bitfield will never span two bytes;
    > padding bits will be inserted if necessary to justify it in its own
    > byte.


    bitfield of declared type T - I originally thought that bitfields
    were of bit-field-type, that K&R could have created a new reserved/key
    word for, such as 'bitf', if desired.

    not real code:
    struct {
    unsigned bitf x : 5;
    unsigned bitf y : 5;
    signed bitf z : 6;
    } nabs;

    But it seems now that type has more meaning.

    Therefore, the struct definition
    >
    > struct {
    > unsigned char x : 5;
    > unsigned char y : 5;
    > } nabs;
    >
    > will correspond on "most" compilers to xxxxx000yyyyy000, while
    >
    > struct {
    > unsigned short x : 5;
    > unsigned short y : 5;
    > } nabs;
    >
    > will correspond to xxxxxyyyyy000000.
    >

    If you care about that kind of micro-optimization,
    > you probably welcome the extra tiny bit of control over alignment given
    > to you by the "de-facto" standard.
    > The issue may originally have been that unaligned memory accesses are
    > terribly slow on most platforms; therefore, it makes sense to allow the
    > programmer to force byte-alignment or word-alignment with a minimum of
    > fuss. (C99 introduced anonymous bitfields to deal with the same issue.)
    > The issue now is certainly compatibility with other compilers. Peer
    > pressure is a strong force in the compiler field.


    When you interface with hardware or send packed data between CPUs
    the bits have to be exact which is probably the primary motivation
    here.

    >
    > N869 section 6.7.2.1#9 seems to encourage the "de-facto" behavior:
    >
    > [#9] An implementation may allocate any addressable storage
    > unit large enough to hold a bit-field. 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. 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. The
    > order of allocation of bit-fields within a unit (high-order
    > to low-order or low-order to high-order) is implementation-
    > defined. The alignment of the addressable storage unit is
    > unspecified.
    >
    > > Obviously programmers want to use bit-field objects that may be
    > > smaller or larger than standard integer size shouldn't the standard
    > > support that.

    >
    > No. If there's no Standard support for 128-bit integer math, it
    > seems pretty silly to require implementations to support integer
    > math on bitfields of type "signed int foo : 128". That would put a
    > huge burden on implementors to deal with arbitrarily-wide integer
    > math, while making users jump through silly hoops to get at it.


    I stand corrected the standard shouldn't force the use of these bit-
    field types but maybe have an optional supplement/section that would
    encourage compilers to extend in the same manner.
     
    , Feb 24, 2007
    #6
  7. "Arthur J. O'Dwyer" <> wrote
    > No. If there's no Standard support for 128-bit integer math, it
    > seems pretty silly to require implementations to support integer
    > math on bitfields of type "signed int foo : 128". That would put a
    > huge burden on implementors to deal with arbitrarily-wide integer
    > math, while making users jump through silly hoops to get at it.
    >

    Not a huge burden. It's another job which someone writing a quick and
    cheerful compiler could probably do without, but no harder than implenting
    floating -point arithmetic on machines without hardware float registers, for
    instance.
     
    Malcolm McLean, Feb 24, 2007
    #7
    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. Replies:
    3
    Views:
    1,847
    Timothy Bendfelt
    Jan 19, 2007
  2. Replies:
    9
    Views:
    1,046
    Juha Nieminen
    Aug 22, 2007
  3. Peter Michaux

    de facto standard C unit testing framework?

    Peter Michaux, Mar 21, 2008, in forum: C Programming
    Replies:
    1
    Views:
    408
    Ian Collins
    Mar 21, 2008
  4. Krumble Bunk

    the de-facto way to "parse" input

    Krumble Bunk, Jun 11, 2008, in forum: C Programming
    Replies:
    8
    Views:
    318
  5. Jeff.M
    Replies:
    6
    Views:
    202
    Lasse Reichstein Nielsen
    May 4, 2009
Loading...

Share This Page