bit specific structure

Sometimes you need to construct a structure which the variables in the structure is not specified in bytes, instead bits. It may occur when you wanna construct some field of a binaries packets for examples Point Code field in Called address of TCAP packet.

One of the point code format length is 14 bits, consist of 3 parts (x,y,z). Where x is 3 bits, y is 8 bits, and z again 3 bits. How we suppose feed the x,y,z to form a 2 bytes data? 2 bytes is 16 bits, that means 14 bits padding with 2 bits ZERO.

One of the common solution is write a function with 3 params (x,y,z) to perform shifting bits and returns a 2 bytes characters array. But it is tedious to write such function and the complexity will grows if the number of params increases.

Therefore, bit specific structure is used instead. To construct a bit specific structure, there are few things have to be taken care precisely.
1. Variable type used
2. Whether to use __attribute__((packed)) or not.

Lets look at the definition of the ERRORNOUS PointCode structure:


typedef struct
{
     char      x:3,
               y:8,
               z:3;
}PointCode;

The way of define bit specific structure is correct, but the outcome will be errornous.


PointCode pc;
printf("%d ",sizeof(pc));

The sizeof(pc) will return 3 bytes instead of two bytes. Reason is because, the structure uses variable type that is not large enough to store a 2 bytes data.

Second attempt will be still ERRORNOUS where we uses unsigned long instead of char.


typedef struct
{
     unsigned long       x:3,
                         y:8,
                         z:3;
}PointCode;

unsigned long is 4 bytes, after storing the data, the remaining 2 bytes will be padded with 0. Therefore the sizeof will return 4 bytes, which is not what we wanted, what we want is 2 bytes.

The CORRECT definition at last:


typedef struct
{
     unsigned long    x:3,
                      y:8,
                      z:3;
}__attribute__((packed)) PointCode;

With __attribute__((packed)), it tells the compiler to packed the data, now it returns exactly 14 bits, and sizeof will return 2 bytes. You may want to verify the correctness of the data.

PointCode PC;
memset(&pc,0,sizeof(pc));

pc.x=1;
pc.y=2;
pc.z=3;

unsigned char* ptr=(unsigned char*)&pc;

printf("size(%d) payload: (%X %X) ",sizeof(pc), *ptr, *(ptr+1));

2 thoughts on “bit specific structure

  1. typedef struct
    {
    unsigned int x:3,
    unsigned long y:2,
    unsigned long z:3;
    }PointCode;

    then
    PointCode pc;
    printf(“%d “,sizeof(pc)); ?

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>