471,049 Members | 1,869 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,049 software developers and data experts.

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

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?

Oct 19 '05 #1
8 17265
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

Oct 19 '05 #2
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)
Oct 19 '05 #3
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)
Oct 19 '05 #4
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

Oct 19 '05 #5
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

Oct 19 '05 #6
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)
Oct 19 '05 #7
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

Oct 19 '05 #8
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)
Oct 19 '05 #9

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

13 posts views Thread by Vincezo Ciaschini | last post: by
140 posts views Thread by Oliver Brausch | last post: by
100 posts views Thread by E. Robert Tisdale | last post: by
5 posts views Thread by Mike | last post: by
5 posts views Thread by .rhavin grobert | last post: by
32 posts views Thread by Stephen Horne | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.