aling said:
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