__attribute__ ((aligned(2)) vs. __attribute__ ( (__packed__))

Because alignment, the size of this data structure is 28, instead of 26.

typedef struct tWAVEFORMATEX
{
    u_int32_t   fcc;
    u_int32_t   cb;
    u_int16_t   wFormatTag;         /* format type */
    u_int16_t   nChannels;          /* number of channels (i.e. mono, stereo...) */
    u_int32_t   nSamplesPerSec;     /* sample rate */
    u_int32_t   nAvgBytesPerSec;    /* for buffer estimation */
    u_int16_t   nBlockAlign;        /* block size of data */
    u_int16_t   wBitsPerSample;     /* number of bits per sample of mono data */
    u_int16_t   cbSize;             /* the count in bytes of the size of */
    /* extra information (after cbSize) */
} WAVEFORMATEX;

 
However, you want to read data from a file into the structure. Then how to do so?
What makes it worse is when there are following set of data which should be read into another data structure. Because the size of above structure is 28 due to the alignment, it starts reading next data from the 29th bytes instead of 27th bytes.

Then how to solve it?
You can tell the compiler to abide by original data layout which is same to the one denoted by the structure.
So, you will try issue :

typedef struct.... {
 ...
} WAVEFORMATEX __attribute__ ( (aligned(2)) );

or you may try adding the __attribute__ to each data field declaration like this.

typedef struct tWAVEFORMATEX
{
    u_int32_t   fcc __attribute__ ( (aligned(2)) );
    u_int32_t   cb __attribute__ ( (aligned(2)) );
    u_int16_t   wFormatTag __attribute__ ( (aligned(2)) );         /* format type */
    u_int16_t   nChannels __attribute__ ( (aligned(2)) );          /* number of channels (i.e. mono, stereo...) */
    u_int32_t   nSamplesPerSec __attribute__ ( (aligned(2)) );     /* sample rate */
    u_int32_t   nAvgBytesPerSec;    /* for buffer estimation */
    u_int16_t   nBlockAlign;        /* block size of data */
    u_int16_t   wBitsPerSample __attribute__ ( (aligned(2)) );     /* number of bits per sample of mono data */
    u_int16_t   cbSize __attribute__ ( (aligned(2)) );             /* the count in bytes of the size of */
    /* extra information (after cbSize) */
} WAVEFORMATEX;

(Actually, what matters is the last field, cbSize. )
However, they don’t work.

Then how to work around this problem?

The minimum size of structure, ie. 26, can be ensured by writing it this way : 

typedef struct __attribute__ ( (__packed__)) tWAVEFORMATEX
{
    u_int32_t   fcc;
    u_int32_t   cb;
    u_int16_t   wFormatTag;         /* format type */
    u_int16_t   nChannels;          /* number of channels (i.e. mono, stereo...) */
    u_int32_t   nSamplesPerSec;     /* sample rate */
    u_int32_t   nAvgBytesPerSec;    /* for buffer estimation */
    u_int16_t   nBlockAlign;        /* block size of data */
    u_int16_t   wBitsPerSample;     /* number of bits per sample of mono data */
    u_int16_t   cbSize;             /* the count in bytes of the size of */
    /* extra information (after cbSize) */
} WAVEFORMATEX;

3 responses to this post.

  1. Posted by Vlad on August 9, 2009 at 12:09 PM

    Thanks, I was looking for ways to pack structs on iPhone and your solution worked. How did you find it?

    Reply

    • Posted by jongampark on August 9, 2009 at 7:29 PM

      It is common thing to use in C/C++. It was just buried in the GCC document. There are many good features in GCC. However be careful when you use GCC-only features. Here in US, I saw lots of programmers who think they were smart by using those kind of features, which will make porting to other platform very difficult in the end.

      Reply

  2. Posted by claf on March 30, 2011 at 1:16 AM

    Note that this doesn’t seem to work right if you try to combine the typedef and the struct definition or if you combine variable declarations with the structure definition.

    Reply

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: