What's the memory layout of bit field struct in little-endian and big-endian platform?

Discussion in 'C++' started by aling, Oct 19, 2005.

  1. aling

    aling Guest

    Given the bit field struct:

    int main()
    {
    union
    {
    struct
    {
    unsigned short s1 : 4;
    unsigned short s2 : 3;
    unsigned short s3 : 2;
    } x;
    char c;
    } v;
    v.c = 0x7A; // 0111 1010 b
    printf( "%X", v.x.s3 );
    }

    What's the memory layout of bit field struct v after set v.c=0x7A in
    little-endian platform and big-endian platform?
    aling, Oct 19, 2005
    #1
    1. Advertising

  2. aling

    mlimber Guest

    aling wrote:
    > Given the bit field struct:
    >
    > int main()
    > {
    > union
    > {
    > struct
    > {
    > unsigned short s1 : 4;
    > unsigned short s2 : 3;
    > unsigned short s3 : 2;
    > } x;
    > char c;
    > } v;
    > v.c = 0x7A; // 0111 1010 b
    > printf( "%X", v.x.s3 );
    > }
    >
    > What's the memory layout of bit field struct v after set v.c=0x7A in
    > little-endian platform and big-endian platform?


    It is unspecified and implementation-dependent. You should avoid
    bitfields in C++ because:

    1. They are non-portable, as you seem to have learned the hard way.
    C++ARM says that the layout of bit-fields "is highly implementation
    dependent, and it is wise not to make any assumptions about it unless
    absolutely necessary." On a previous project, we used bit-fields for
    mapping the contents of hardware registers, but when we eventually
    ported the project to another platform with the other endianness, we
    had to manually reverse the order of our many bit-fields. If I had time
    and was still working on that project, I might try to use template
    metaprogramming (a la Boost and Modern C++ Design) to engineer a more
    portable solution akin to the Boost Parameter library
    (http://boost.org/libs/parameter/doc/html/index.html). (N.B., I haven't
    looked to see if anything like that already exists, and you might want
    to. Compare this article discussing bitstreams in C++
    http://www.cuj.com/documents/s=9897/cuj0510bishop/0510bishop.html .)

    2. Some programmers mistakenly see bit-fields as a good form of space
    or speed optimization. Consult C++ARM section 9.6 and C++PL section
    C.8.1 for reasons why these forms of premature optimization often have
    the opposite effect. In certain scenarios, bandwidth bottlenecks
    *might* be eased by bit-packing. Just remember not to prematurely
    optimize (http://www.gotw.ca/publications/mill09.htm). :)

    Cheers! --M
    mlimber, Oct 19, 2005
    #2
    1. Advertising

  3. aling

    Pete Becker Guest

    Re: What's the memory layout of bit field struct in little-endianand big-endian platform?

    aling wrote:
    >
    > What's the memory layout of bit field struct v after set v.c=0x7A in
    > little-endian platform and big-endian platform?
    >


    The C and C++ languages both say that after you've assigned to one
    member of a union you can't read from other members. The behavior of
    your code is undefined.

    The other issue is that the layout of bitfields is
    implementation-defined. Read your compiler's documentation to see what
    they do.

    --

    Pete Becker
    Dinkumware, Ltd. (http://www.dinkumware.com)
    Pete Becker, Oct 19, 2005
    #3
  4. aling

    Pete Becker Guest

    Re: What's the memory layout of bit field struct in little-endianand big-endian platform?

    mlimber wrote:
    >
    > It is unspecified and implementation-dependent. You should avoid
    > bitfields in C++ because:


    You should use bitfields when they are appropriate.

    >
    > 1. They are non-portable,


    Yes, that is correct. When you need 'em you need 'em. Non-portable is
    often far more useful than strictly conforming code that doesn't
    actually work with some compilers.

    > as you seem to have learned the hard way.


    Well, more important is the misuse of the union.

    > C++ARM says that the layout of bit-fields "is highly implementation
    > dependent, and it is wise not to make any assumptions about it unless
    > absolutely necessary." On a previous project, we used bit-fields for
    > mapping the contents of hardware registers, but when we eventually
    > ported the project to another platform with the other endianness, we
    > had to manually reverse the order of our many bit-fields. If I had time
    > and was still working on that project, I might try to use template
    > metaprogramming (a la Boost and Modern C++ Design) to engineer a more
    > portable solution akin to the Boost Parameter library
    > (http://boost.org/libs/parameter/doc/html/index.html). (N.B., I haven't
    > looked to see if anything like that already exists, and you might want
    > to. Compare this article discussing bitstreams in C++
    > http://www.cuj.com/documents/s=9897/cuj0510bishop/0510bishop.html .)


    It's much simpler to just rewrite the code that needs to be changed.
    It's not that big. Portability is about being able to move across
    platforms easily, and that means isolating platform-dependent code so
    that it's easily identified and easily modified. Of course, that's
    Old-Fashioned Design (TM), and I'm sure you can have much more fun, and
    spend far more time, writing meta-programmed monstrosities that do part
    of the job. Personally, I prefer productivity to cleverness.

    --

    Pete Becker
    Dinkumware, Ltd. (http://www.dinkumware.com)
    Pete Becker, Oct 19, 2005
    #4
  5. aling

    mlimber Guest

    Pete Becker wrote:
    > mlimber wrote:

    [snip]
    > > C++ARM says that the layout of bit-fields "is highly implementation
    > > dependent, and it is wise not to make any assumptions about it unless
    > > absolutely necessary." On a previous project, we used bit-fields for
    > > mapping the contents of hardware registers, but when we eventually
    > > ported the project to another platform with the other endianness, we
    > > had to manually reverse the order of our many bit-fields. If I had time
    > > and was still working on that project, I might try to use template
    > > metaprogramming (a la Boost and Modern C++ Design) to engineer a more
    > > portable solution akin to the Boost Parameter library
    > > (http://boost.org/libs/parameter/doc/html/index.html). (N.B., I haven't
    > > looked to see if anything like that already exists, and you might want
    > > to. Compare this article discussing bitstreams in C++
    > > http://www.cuj.com/documents/s=9897/cuj0510bishop/0510bishop.html .)

    >
    > It's much simpler to just rewrite the code that needs to be changed.
    > It's not that big. Portability is about being able to move across
    > platforms easily, and that means isolating platform-dependent code so
    > that it's easily identified and easily modified.


    Ease of rewriting is application-specific, methinks. If there are a
    multiplicity of bit-field structures and several varying compiler
    implementations that they need to work with, things can get ugly for
    several reasons. Rewriting will probably entail a lot of error-prone
    cut-and-pasting, and it should be noted that it's difficult to write
    test code for such things because that test code would also vary
    between platforms. So, I would argue that it could be a big deal after
    all, especially for mission-critical type work.

    > Of course, that's
    > Old-Fashioned Design (TM), and I'm sure you can have much more fun, and
    > spend far more time, writing meta-programmed monstrosities that do part
    > of the job. Personally, I prefer productivity to cleverness.


    Well, I should first probably confess that I have used bit-fields
    myself since working on the aforementioned project, but I did so mainly
    because I lacked a better facility and didn't have time to metaprogram
    one. I wish I had such a library, though, because it would allow me to
    drop bit-fields altogether and have a portable (in the sense that it
    compiles and works without modification) with a wide variety of
    platforms and compilers. If such a library existed, many embedded
    programmers would be saved a lot of dull, error-prone porting work.

    Cheers! --M
    mlimber, Oct 19, 2005
    #5
  6. aling

    Greg Guest

    aling wrote:
    > Given the bit field struct:
    >
    > int main()
    > {
    > union
    > {
    > struct
    > {
    > unsigned short s1 : 4;
    > unsigned short s2 : 3;
    > unsigned short s3 : 2;
    > } x;
    > char c;
    > } v;
    > v.c = 0x7A; // 0111 1010 b
    > printf( "%X", v.x.s3 );
    > }
    >
    > What's the memory layout of bit field struct v after set v.c=0x7A in
    > little-endian platform and big-endian platform?


    Being implementation-dependent, the layout of the bitfield does not
    conform to any one standard. In fact, a bitfield may be laid out the
    same way on both big-endian and little-endian machines. Metrowerks
    CodeWarrior, for example, has a #pragma reverse_bitfields that does
    exactly that. (you may wonder who needs such a pragma - this pragma was
    added so that Microsoft could compile Macintosh Office with
    CodeWarrior).

    Greg
    Greg, Oct 19, 2005
    #6
  7. aling

    Pete Becker Guest

    Re: What's the memory layout of bit field struct in little-endianand big-endian platform?

    mlimber wrote:
    >
    > Ease of rewriting is application-specific, methinks.


    Obviously.

    > If there are a
    > multiplicity of bit-field structures and several varying compiler
    > implementations that they need to work with, things can get ugly for
    > several reasons. Rewriting will probably entail a lot of error-prone
    > cut-and-pasting,


    Properly designed macros are usually a better solution than cut-and-paste.

    > and it should be noted that it's difficult to write
    > test code for such things because that test code would also vary
    > between platforms. So, I would argue that it could be a big deal after
    > all, especially for mission-critical type work.
    >


    Yes, writing portable code isn't trivial. Neither is meta-programming.
    Either way, though, you damned well better be able to test what you've
    done. "It's too hard" doesn't cut it.

    >
    >>Of course, that's
    >>Old-Fashioned Design (TM), and I'm sure you can have much more fun, and
    >>spend far more time, writing meta-programmed monstrosities that do part
    >>of the job. Personally, I prefer productivity to cleverness.

    >
    >
    > Well, I should first probably confess that I have used bit-fields
    > myself since working on the aforementioned project, but I did so mainly
    > because I lacked a better facility and didn't have time to metaprogram
    > one.


    You've just agreed with what I said. To put it more strongly: bitfields
    work just fine for what they are designed to do. Which is probably why
    there is no "better facility" through metaprogramming.

    > I wish I had such a library, though, because it would allow me to
    > drop bit-fields altogether and have a portable (in the sense that it
    > compiles and works without modification) with a wide variety of
    > platforms and compilers. If such a library existed, many embedded
    > programmers would be saved a lot of dull, error-prone porting work.
    >


    Well, maybe a small amount of moderately dull porting work. It's no more
    error prone than relying on a library that attempts to detect the
    essential criteria for laying out bit fields that are inherently
    non-portable. And, of course, the way to make sure that porting the
    bitfield code isn't error-prone is to write test cases, and use them.

    --

    Pete Becker
    Dinkumware, Ltd. (http://www.dinkumware.com)
    Pete Becker, Oct 19, 2005
    #7
  8. aling

    mlimber Guest

    Pete Becker wrote:
    > mlimber wrote:
    > >
    > > Ease of rewriting is application-specific, methinks.

    >
    > Obviously.
    >
    > > If there are a
    > > multiplicity of bit-field structures and several varying compiler
    > > implementations that they need to work with, things can get ugly for
    > > several reasons. Rewriting will probably entail a lot of error-prone
    > > cut-and-pasting,

    >
    > Properly designed macros are usually a better solution than cut-and-paste.


    But then we're not talking about rewriting any more. Or, rather, we're
    talking about rewriting the macros, and there's not so great a
    difference in porting a preprocessor library and a metaprogrammed one.

    > > and it should be noted that it's difficult to write
    > > test code for such things because that test code would also vary
    > > between platforms. So, I would argue that it could be a big deal after
    > > all, especially for mission-critical type work.
    > >

    >
    > Yes, writing portable code isn't trivial. Neither is meta-programming.
    > Either way, though, you damned well better be able to test what you've
    > done. "It's too hard" doesn't cut it.


    Agreed.

    > > Well, I should first probably confess that I have used bit-fields
    > > myself since working on the aforementioned project, but I did so mainly
    > > because I lacked a better facility and didn't have time to metaprogram
    > > one.

    >
    > You've just agreed with what I said. To put it more strongly: bitfields
    > work just fine for what they are designed to do. Which is probably why
    > there is no "better facility" through metaprogramming.


    Perhaps, but the fact that this same question gets posted repeatedly on
    this newsgroup may indicate a yearning of some kind. :) (See also the
    similar-but-different article in CUJ that I cited in my first post.)

    >
    > > I wish I had such a library, though, because it would allow me to
    > > drop bit-fields altogether and have a portable (in the sense that it
    > > compiles and works without modification) with a wide variety of
    > > platforms and compilers. If such a library existed, many embedded
    > > programmers would be saved a lot of dull, error-prone porting work.
    > >

    >
    > Well, maybe a small amount of moderately dull porting work. It's no more
    > error prone than relying on a library that attempts to detect the
    > essential criteria for laying out bit fields that are inherently
    > non-portable. And, of course, the way to make sure that porting the
    > bitfield code isn't error-prone is to write test cases, and use them.


    The metaprogrammed solution that I am thinking of would manually
    assemble the "bit-field" inside a standard integral type with explicit
    bit-twiddling operations and would thus avoid implementation
    dependencies for bit-fields. There is no way to detect, say, endinaness
    at compile-time, but a few simple tests run in a library configuration
    should easily be able to determine the right compiler/processor
    configuration (and that's true of a macro library or a metaprogrammed
    one). The library should, of course, supply a thorough set of tests for
    itself that can be run on each platform.

    Cheers! --M
    mlimber, Oct 19, 2005
    #8
  9. aling

    Pete Becker Guest

    Re: What's the memory layout of bit field struct in little-endianand big-endian platform?

    mlimber wrote:
    > Pete Becker wrote:
    >
    >>mlimber wrote:
    >>
    >>>Ease of rewriting is application-specific, methinks.

    >>
    >>Obviously.
    >>
    >>
    >>>If there are a
    >>>multiplicity of bit-field structures and several varying compiler
    >>>implementations that they need to work with, things can get ugly for
    >>>several reasons. Rewriting will probably entail a lot of error-prone
    >>>cut-and-pasting,

    >>
    >>Properly designed macros are usually a better solution than cut-and-paste.

    >
    >
    > But then we're not talking about rewriting any more. Or, rather, we'r
    > talking about rewriting the macros, and there's not so great a
    > difference in porting a preprocessor library and a metaprogrammed one.


    I look forward to seeing your design for a metaprogrammed library that
    manages bitfields. Until then, I'll continue to use macros.

    --

    Pete Becker
    Dinkumware, Ltd. (http://www.dinkumware.com)
    Pete Becker, Oct 19, 2005
    #9
    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. invincible
    Replies:
    1
    Views:
    543
    red floyd
    Jun 14, 2005
  2. Eric J.Hu
    Replies:
    3
    Views:
    834
    Alexei A. Frounze
    Aug 29, 2005
  3. Replies:
    5
    Views:
    347
    Stephen Sprunk
    Aug 31, 2006
  4. Eric J.Hu
    Replies:
    7
    Views:
    531
    Jim Langston
    Sep 7, 2005
  5. bhatia

    Big Endian and Little Endian

    bhatia, Jul 7, 2006, in forum: C++
    Replies:
    2
    Views:
    477
    Robbie Hatley
    Jul 7, 2006
Loading...

Share This Page