Re: structure packing

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 16/01/14 11:45, vijay nag wrote:
> Dear gcc,
> 
> Why is the size of below struct UnPackedStruct 6 ? Is there any switch
> similar to -E in gcc to check how data alignment is performed by GCC
> for structs ?
> 

What were you expecting for the sizes?  gcc is following the packing and
alignment rules of C and your current platform (I'm guessing it is x86 -
certainly something with 32-bit ints with 32-bit natural alignment).

The first two fields of tlv_header_t are packed into a single 8-bit
unsigned char.  You then have another 8-bit field, so the 16-bit
tlv_type is placed immediately with 2-byte alignment.  tlv_header_t is
thus 4 bytes in size, with a 2-byte alignment.

In UnPackedStruct, you have a 4-byte field with 2-byte alignment,
followed by a 1-byte field.  But the struct must be at least a multiple
of 2 bytes, so that arrays of it will have 2-byte alignment (required
for the tlv_header_t field).  Thus the compiler adds a padding byte,
bringing it up to 6 bytes total.

You can use the -Wpadded flag to check when padding is added for
alignment purposes.  And you could use the "packed" attribute on the
structure if you /really/ need tight packing, but be aware that it could
result in inefficient code (and even invalid code on some platforms).
Generally, if you need tight control over the padding and alignment it
is best to use -Wpadded along with explicit "dummy" or "padding" fields
and check the size of the resulting types.

mvh.,

David



> 
> #include <stdio.h>
> #include <stdint.h>
> 
> struct tlv_header_t {
>     unsigned char tlv_length_upper : 3;
>     unsigned char reserved : 5;
>     unsigned char tlv_length_lower;
>     uint16_t tlv_type;
> };
> 
> typedef struct {
>   struct tlv_header_t  sess;
>   uint8_t p;
> } UnPackedStruct;
> 
> typedef struct {
>    int a;
>    char b;
> } PaddedStruct;
> 
> int main()
> {
>   UnPackedStruct a;
>   PaddedStruct b;
> 
>   printf("size of a = %u\n", sizeof(a));
>   printf("size of b = %u\n", sizeof(b));
> 
>   return 1;
> }
> 
> ./padding
> size of a = 6
> size of b = 8
> 





[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux