Help - Bit fields ...

How does the GNU compiler allocate bit fields !

I am trying to decode a message that is defined as follows

Parameter No of bits
A 8
B 6
C 210 ( 253 bits - various configurations )
W 2
X 24
Y 1
Z 5

Total of 256 bits

I have found that the following works (a least to extract the B field)

typedef struct GEN_ts_tag
{
unsigned A :8;
AAAAAAAA
unsigned C1 :2;
unsigned B :6;
BBBBBBCC
unsigned C2 :16; // - 32 bits so far
CCCCCCCC

CCCCCCCC
unsigned C3[6]; // - 192 more bits
CCCCCCCC …

unsigned W :2;
XXXXXXWW
unsigned X1 :6;
XXXXXXXX
unsigned X :18;
XXXXXXXX
unsigned Y :1;
unsigned Z :5;
XXXYZZZZZ
} GEN_ts;
typedef GEN_ts * pGEN_ts;

I expected to be able to assign the fields as follows

typedef struct GEN_ts_tag
{
unsigned A :8;
unsigned B :6;
unsigned C1 :18; // - 32 bits so far

unsigned C[6]; // - 192 more bits

unsigned W :2;
unsigned X :24;
unsigned Y :1;
unsigned Z :5;
} GEN_ts;
typedef GEN_ts * pGEN_ts;

I realize that I have some sort of endian mental block.

There are two issues here. First, as you noticed, is the endianess. The
second is packing. Who/what is generating this data? Who/what is
transporting it?

Can you confirm that your looking at 32 bytes (256/8)?

Can you force a message to be generated where you can look at the bits
received to determine how to interpret them.

If you are both the generator and receiver of the data it should be pretty
easy.


“Michael Nunan” <m.nunan@ieee.ca> wrote in message
news:ah2559$1ni$1@inn.qnx.com

How does the GNU compiler allocate bit fields !

I am trying to decode a message that is defined as follows

Parameter No of bits
A 8
B 6
C 210 ( 253 bits - various configurations )
W 2
X 24
Y 1
Z 5

Total of 256 bits

I have found that the following works (a least to extract the B field)

typedef struct GEN_ts_tag
{
unsigned A :8;
AAAAAAAA
unsigned C1 :2;
unsigned B :6;
BBBBBBCC
unsigned C2 :16; // - 32 bits so far
CCCCCCCC

CCCCCCCC
unsigned C3[6]; // - 192 more bits
CCCCCCCC …

unsigned W :2;
XXXXXXWW
unsigned X1 :6;
XXXXXXXX
unsigned X :18;
XXXXXXXX
unsigned Y :1;
unsigned Z :5;
XXXYZZZZZ
} GEN_ts;
typedef GEN_ts * pGEN_ts;

I expected to be able to assign the fields as follows

typedef struct GEN_ts_tag
{
unsigned A :8;
unsigned B :6;
unsigned C1 :18; // - 32 bits so far

unsigned C[6]; // - 192 more bits

unsigned W :2;
unsigned X :24;
unsigned Y :1;
unsigned Z :5;
} GEN_ts;
typedef GEN_ts * pGEN_ts;

I realize that I have some sort of endian mental block.

The data is packed - 256 bit ocupy 256 bits of message. I have tried
decoding the messages as basic byte arrays - the problem is that there are
only a few fields where I can predict the correct values. What I want to
know is how the compiler creates its bit fields. The expected data is

AAAAAAAA BBBBBBCC CCCCCCCC CCCCCCCC CCCCCCCC…CCCCCCCC XXXXXXWW XXXXXXXX
XXXXXXXX XXXYZZZZZ

using the following I get the expected values for BBBBBB

typedef struct GEN_ts_tag
{
unsigned A :8;
unsigned B :6;
unsigned C1 :18; // - 32 bits so far

unsigned C[6]; // - 192 more bits

  • must generate AAAAAAAA BBBBBBCC

using this structure I get BBBBBBBB << 2

typedef struct GEN_ts_tag
{
unsigned A :8;
unsigned B :6;
unsigned C1 :18; // - 32 bits so far

  • must generate AAAAAAAA CCBBBBBB CCCCCCCC CCCCCCCC …



    “Bill Caroselli (Q-TPS)” <QTPS@EarthLink.net> wrote in message
    news:ah28ll$42u$1@inn.qnx.com

There are two issues here. First, as you noticed, is the endianess. The
second is packing. Who/what is generating this data? Who/what is
transporting it?

Can you confirm that your looking at 32 bytes (256/8)?

Can you force a message to be generated where you can look at the bits
received to determine how to interpret them.

If you are both the generator and receiver of the data it should be pretty
easy.


“Michael Nunan” <> m.nunan@ieee.ca> > wrote in message
news:ah2559$1ni$> 1@inn.qnx.com> …
How does the GNU compiler allocate bit fields !

I am trying to decode a message that is defined as follows

Parameter No of bits
A 8
B 6
C 210 ( 253 bits - various configurations )
W 2
X 24
Y 1
Z 5

Total of 256 bits

I have found that the following works (a least to extract the B field)

typedef struct GEN_ts_tag
{
unsigned A :8;
AAAAAAAA
unsigned C1 :2;
unsigned B :6;
BBBBBBCC
unsigned C2 :16; // - 32 bits so far
CCCCCCCC

CCCCCCCC
unsigned C3[6]; // - 192 more bits
CCCCCCCC …

unsigned W :2;
XXXXXXWW
unsigned X1 :6;
XXXXXXXX
unsigned X :18;
XXXXXXXX
unsigned Y :1;
unsigned Z :5;
XXXYZZZZZ
} GEN_ts;
typedef GEN_ts * pGEN_ts;

I expected to be able to assign the fields as follows

typedef struct GEN_ts_tag
{
unsigned A :8;
unsigned B :6;
unsigned C1 :18; // - 32 bits so far

unsigned C[6]; // - 192 more bits

unsigned W :2;
unsigned X :24;
unsigned Y :1;
unsigned Z :5;
} GEN_ts;
typedef GEN_ts * pGEN_ts;

I realize that I have some sort of endian mental block.
\

I suggest you use you struct with it’s bit fields, initialize data in a
sample program and look at the results in hex.

“Michael Nunan” <m.nunan@ieee.ca> wrote in message
news:ah29b2$4el$1@inn.qnx.com

The data is packed - 256 bit ocupy 256 bits of message. I have tried
decoding the messages as basic byte arrays - the problem is that there are
only a few fields where I can predict the correct values. What I want to
know is how the compiler creates its bit fields. The expected data is

AAAAAAAA BBBBBBCC CCCCCCCC CCCCCCCC CCCCCCCC…CCCCCCCC XXXXXXWW XXXXXXXX
XXXXXXXX XXXYZZZZZ

using the following I get the expected values for BBBBBB

typedef struct GEN_ts_tag
{
unsigned A :8;
unsigned B :6;
unsigned C1 :18; // - 32 bits so far

unsigned C[6]; // - 192 more bits

  • must generate AAAAAAAA BBBBBBCC

using this structure I get BBBBBBBB << 2

typedef struct GEN_ts_tag
{
unsigned A :8;
unsigned B :6;
unsigned C1 :18; // - 32 bits so far

  • must generate AAAAAAAA CCBBBBBB CCCCCCCC CCCCCCCC …



    “Bill Caroselli (Q-TPS)” <> QTPS@EarthLink.net> > wrote in message
    news:ah28ll$42u$> 1@inn.qnx.com> …
    There are two issues here. First, as you noticed, is the endianess.
    The
    second is packing. Who/what is generating this data? Who/what is
    transporting it?

Can you confirm that your looking at 32 bytes (256/8)?

Can you force a message to be generated where you can look at the bits
received to determine how to interpret them.

If you are both the generator and receiver of the data it should be
pretty
easy.


“Michael Nunan” <> m.nunan@ieee.ca> > wrote in message
news:ah2559$1ni$> 1@inn.qnx.com> …
How does the GNU compiler allocate bit fields !

I am trying to decode a message that is defined as follows

Parameter No of bits
A 8
B 6
C 210 ( 253 bits - various configurations )
W 2
X 24
Y 1
Z 5

Total of 256 bits

I have found that the following works (a least to extract the B field)

typedef struct GEN_ts_tag
{
unsigned A :8;
AAAAAAAA
unsigned C1 :2;
unsigned B :6;
BBBBBBCC
unsigned C2 :16; // - 32 bits so far
CCCCCCCC

CCCCCCCC
unsigned C3[6]; // - 192 more bits
CCCCCCCC …

unsigned W :2;
XXXXXXWW
unsigned X1 :6;
XXXXXXXX
unsigned X :18;
XXXXXXXX
unsigned Y :1;
unsigned Z :5;
XXXYZZZZZ
} GEN_ts;
typedef GEN_ts * pGEN_ts;

I expected to be able to assign the fields as follows

typedef struct GEN_ts_tag
{
unsigned A :8;
unsigned B :6;
unsigned C1 :18; // - 32 bits so far

unsigned C[6]; // - 192 more bits

unsigned W :2;
unsigned X :24;
unsigned Y :1;
unsigned Z :5;
} GEN_ts;
typedef GEN_ts * pGEN_ts;

I realize that I have some sort of endian mental block.


\

Michael Nunan <m.nunan@ieee.ca> wrote:

The data is packed - 256 bit ocupy 256 bits of message. I have tried
decoding the messages as basic byte arrays - the problem is that there are
only a few fields where I can predict the correct values. What I want to
know is how the compiler creates its bit fields. The expected data is

AAAAAAAA BBBBBBCC CCCCCCCC CCCCCCCC CCCCCCCC…CCCCCCCC XXXXXXWW XXXXXXXX
XXXXXXXX XXXYZZZZZ

using the following I get the expected values for BBBBBB

typedef struct GEN_ts_tag
{
unsigned A :8;
unsigned B :6;
unsigned C1 :18; // - 32 bits so far

unsigned C[6]; // - 192 more bits

Try adding attribute((packed)), that is

typedef struct attribute((packed))
{

}

The compiler is trying to help you make more efficient code, specifying
the attribute packed might make it a bit more relaxed :slight_smile:


regards,
Tom

Thomas Emberson <temberson@softwareremodeling.com> wrote:

Michael Nunan <> m.nunan@ieee.ca> > wrote:
The data is packed - 256 bit ocupy 256 bits of message. I have tried
decoding the messages as basic byte arrays - the problem is that there are
only a few fields where I can predict the correct values. What I want to
know is how the compiler creates its bit fields. The expected data is

AAAAAAAA BBBBBBCC CCCCCCCC CCCCCCCC CCCCCCCC…CCCCCCCC XXXXXXWW XXXXXXXX
XXXXXXXX XXXYZZZZZ

using the following I get the expected values for BBBBBB

typedef struct GEN_ts_tag
{
unsigned A :8;
unsigned B :6;
unsigned C1 :18; // - 32 bits so far

unsigned C[6]; // - 192 more bits

Just took a quick look, and I guess the first question should be, what
processor are you using? x86?

Anyway, with

typedef struct attribute((packed)) GEN_ts_tag
{
unsigned A :8;
unsigned B :6;
unsigned C1 :18;
} test1;

int main()

{
union {
test1 a;
unsigned long b;
} c;

c.a.A = 0;
c.a.B = 63;
c.a.C1 = 0;

printf(" %08X \n", c.b );


c.a.A = 255;
c.a.B = 0;
c.a.C1 = 262143;

printf(" %08X \n", c.b );

c.a.A = 0;
c.a.B = 0;
c.a.C1 = 262143;

printf(" %08X \n", c.b );
}

the output is

00003F00
FFFFC0FF
FFFFC000

with or without the ‘packed’, to me this would be the correct result, no?

regards,
Tom

I’ve run into this situation before. The problem you’re experience is due
to the packing of the fields within your structure. Just because you ask
for a given number of bits to be allocated, does not mean that each field
will be packed on bit boundaries from each other. I’m not sure the default
setting for packing, but it’s definitely not one bit. To acheive your
desired result, enclose your code section with these directives:

#include “_pack1.h”

#include <_packpop.h>

This forces the compiler to place your bit fields on bit boundaries, excatly
as you expected in the first place!

Cheers,
Mike Kadour


“Michael Nunan” <m.nunan@ieee.ca> wrote in message
news:ah2559$1ni$1@inn.qnx.com

How does the GNU compiler allocate bit fields !

I am trying to decode a message that is defined as follows

Parameter No of bits
A 8
B 6
C 210 ( 253 bits - various configurations )
W 2
X 24
Y 1
Z 5

Total of 256 bits

I have found that the following works (a least to extract the B field)

typedef struct GEN_ts_tag
{
unsigned A :8;
AAAAAAAA
unsigned C1 :2;
unsigned B :6;
BBBBBBCC
unsigned C2 :16; // - 32 bits so far
CCCCCCCC

CCCCCCCC
unsigned C3[6]; // - 192 more bits
CCCCCCCC …

unsigned W :2;
XXXXXXWW
unsigned X1 :6;
XXXXXXXX
unsigned X :18;
XXXXXXXX
unsigned Y :1;
unsigned Z :5;
XXXYZZZZZ
} GEN_ts;
typedef GEN_ts * pGEN_ts;

I expected to be able to assign the fields as follows

typedef struct GEN_ts_tag
{
unsigned A :8;
unsigned B :6;
unsigned C1 :18; // - 32 bits so far

unsigned C[6]; // - 192 more bits

unsigned W :2;
unsigned X :24;
unsigned Y :1;
unsigned Z :5;
} GEN_ts;
typedef GEN_ts * pGEN_ts;

I realize that I have some sort of endian mental block.

Mike Kadour <mjkadour@uwaterloo.ca> wrote:

I’ve run into this situation before. The problem you’re experience is due
to the packing of the fields within your structure. Just because you ask
for a given number of bits to be allocated, does not mean that each field
will be packed on bit boundaries from each other.

I would strongly warn against trying to do this with a structure. The reason
being that how bits are packed and endianness will play significant roles in
whether or not your code is successful or not. You are NOT guaranteed that
a future version of the compiler will pack your bits in the same order or
on the same boundaries.
That essentially means that you will not have portable code, and are doing
nothing more than setting yourself up for failure (and a bitch of a debug
session) at some point in the future when one of your tools changes and then
breaks your code in some unpredictable manner.

The safest way to deal with bit structures that are larger than a single
byte is to deal with each byte individually and extract the various bit
fields manually, placing them into your own variables (not-bitmapped) that
will be portable.

If you ever recompile your code on another processor, this will continue
to work, using bit fields in a structure may not.

Cheers,
Camz.

The problems occur when fields span 32bit boundries. I had to create various
wierd masks to get the desired outcome. i.e.

Message is AAAAAAAA BBBBBBCC CCDDEEEE FFFFFFFF

typedef struct X_tag
{
/* member list goes here */
unsigned A :8;

unsigned CH :2; // 2 High order bits of C
unsigned B :6;

unsigned D :2;
unsigned E :4;
unsigned CL :2; // 2 Low order bits of C

unsigned F :8; // first 8 bits of F
}

“Thomas Emberson” <temberson@softwareremodeling.com> wrote in message
news:ah3qec$anq$1@inn.qnx.com

Thomas Emberson <> temberson@softwareremodeling.com> > wrote:
Michael Nunan <> m.nunan@ieee.ca> > wrote:
The data is packed - 256 bit ocupy 256 bits of message. I have tried
decoding the messages as basic byte arrays - the problem is that there
are
only a few fields where I can predict the correct values. What I want
to
know is how the compiler creates its bit fields. The expected data is

AAAAAAAA BBBBBBCC CCCCCCCC CCCCCCCC CCCCCCCC…CCCCCCCC XXXXXXWW
XXXXXXXX
XXXXXXXX XXXYZZZZZ

using the following I get the expected values for BBBBBB

typedef struct GEN_ts_tag
{
unsigned A :8;
unsigned B :6;
unsigned C1 :18; // - 32 bits so far

unsigned C[6]; // - 192 more bits


Just took a quick look, and I guess the first question should be, what
processor are you using? x86?

Anyway, with

typedef struct attribute((packed)) GEN_ts_tag
{
unsigned A :8;
unsigned B :6;
unsigned C1 :18;
} test1;

int main()

{
union {
test1 a;
unsigned long b;
} c;

c.a.A = 0;
c.a.B = 63;
c.a.C1 = 0;

printf(" %08X \n", c.b );


c.a.A = 255;
c.a.B = 0;
c.a.C1 = 262143;

printf(" %08X \n", c.b );

c.a.A = 0;
c.a.B = 0;
c.a.C1 = 262143;

printf(" %08X \n", c.b );
}

the output is

00003F00
FFFFC0FF
FFFFC000

with or without the ‘packed’, to me this would be the correct result, no?

regards,
Tom

I agree - I made it work but it was a real pain in the neck. I had to break
up the data into 8 bit regions
and then reassemble the fields to use them.

<camz@passageway.com> wrote in message news:ah41i9$epp$2@inn.qnx.com

Mike Kadour <> mjkadour@uwaterloo.ca> > wrote:
I’ve run into this situation before. The problem you’re experience is
due
to the packing of the fields within your structure. Just because you
ask
for a given number of bits to be allocated, does not mean that each
field
will be packed on bit boundaries from each other.

I would strongly warn against trying to do this with a structure. The
reason
being that how bits are packed and endianness will play significant roles
in
whether or not your code is successful or not. You are NOT guaranteed
that
a future version of the compiler will pack your bits in the same order or
on the same boundaries.
That essentially means that you will not have portable code, and are doing
nothing more than setting yourself up for failure (and a bitch of a debug
session) at some point in the future when one of your tools changes and
then
breaks your code in some unpredictable manner.

The safest way to deal with bit structures that are larger than a single
byte is to deal with each byte individually and extract the various bit
fields manually, placing them into your own variables (not-bitmapped) that
will be portable.

If you ever recompile your code on another processor, this will continue
to work, using bit fields in a structure may not.

Cheers,
Camz.