Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > What's the memory layout of bit field struct in little-endian and big-endian platform?

Reply
Thread Tools

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

 
 
aling
Guest
Posts: n/a
 
      10-19-2005
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?

 
Reply With Quote
 
 
 
 
mlimber
Guest
Posts: n/a
 
      10-19-2005
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/...510bishop.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

 
Reply With Quote
 
 
 
 
Pete Becker
Guest
Posts: n/a
 
      10-19-2005
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)
 
Reply With Quote
 
Pete Becker
Guest
Posts: n/a
 
      10-19-2005
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/...510bishop.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)
 
Reply With Quote
 
mlimber
Guest
Posts: n/a
 
      10-19-2005
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/...510bishop.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

 
Reply With Quote
 
Greg
Guest
Posts: n/a
 
      10-19-2005
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

 
Reply With Quote
 
Pete Becker
Guest
Posts: n/a
 
      10-19-2005
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)
 
Reply With Quote
 
mlimber
Guest
Posts: n/a
 
      10-19-2005
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

 
Reply With Quote
 
Pete Becker
Guest
Posts: n/a
 
      10-19-2005
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)
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Can *common* struct-members of 2 different struct-types, that are thesame for the first common members, be accessed via pointer cast to either struct-type? John Reye C Programming 28 05-08-2012 12:24 AM
Choosing Layout: Css-Layout or Table-Layout hpourfard@gmail.com ASP .Net 1 06-19-2006 10:06 AM
64 bit - Windows Liberty 64bit, Windows Limited Edition 64 Bit, Microsoft SQL Server 2000 Developer Edition 64 Bit, IBM DB2 64 bit - new ! vvcd Computer Support 0 09-17-2004 08:15 PM
struct my_struct *p = (struct my_struct *)malloc(sizeof(struct my_struct)); Chris Fogelklou C Programming 36 04-20-2004 08:27 AM
64 bit - Windows Liberty 64bit, Windows Limited Edition 64 Bit,Microsoft SQL Server 2000 Developer Edition 64 Bit, IBM DB2 64 bit - new! Ionizer Computer Support 1 01-01-2004 07:27 PM



Advertisments