Search code examples
clinuxgccstructurememory-alignment

structure after "packed" still bigger than it should be


Problem is solved. Mistake was not to rethink about given datatypes... The size of following structure is bigger than it should be:

typedef unsigned char    byte;
typedef unsigned short   word;
typedef unsigned long    dword;

struct Y
{
 short      h;
 byte       i;       
}
#if defined (__GNUC__)
    __attribute__((__packed__));
#endif

struct X
{
   short    a;
   byte     b;
   byte     c;
   word     d;
   dword    e;
   byte     f;
   byte     g;
   word     h;
   short    i;
   struct Y G[8];
}
#if defined (__GNUC__)
    __attribute__((__packed__));
#endif

printf("size of X should be 40 but is %i", sizeof(struct X));

Output:

size of X should be 40 but is 44

I need this structure with a size of 40 Bytes (sum of all elements), 44 is the lowest I can reach. Compiler is GCC C, byte is unsigned char, word is unsigned short and dword is unsigned long. sizeof(Y) is 3. What is the problem here?


Solution

  • The types you define are flawed. Ideally I'd suppose that dword should be double the size of word, but you are defining the two as:

    typedef unsigned short   word;  
    typedef unsigned long    dword; 
    

    And it turns out that on your platform sizeof(unsigned short) is 2, while sizeof(unsigned long) is 8, not 4.

    You should really avoid such definitions and use the standard types provided in stdint.h:

    byte  -> uint8_t
    short -> uint16_t
    word  -> uint16_t
    dword -> uint32_t
    

    Finally, your structure declaration is invalid if the macro __GNUC__ is not defined, because you would be missing the final semicolon (;). You can change it to something like this:

    #if defined (__GNUC__)
    __attribute__((__packed__))
    #endif
    struct Y
    {
     uint16_t h;
     uint8_t  i;       
    };