By joetde


2017-02-15 16:53:25 8 Comments

Is there anyway to make gcc pad only at the end of a packed structure?

I am using a packed structure for space optimization, but also use that struct to compute memory offsets (storing multiple structs in a buffer). Therefore if the total size of my struct is not aligned (not a multiple of 4 let's say), if I try to access the following struct in my buffer I will get a SIGBUS.

E.g.

sizeof(my_packed_struct) == 11
sizeof(other_struct) == 12

If I put a my_packed_struct at address 0x2000, I would also put other_struct at 0x200B (+11 bytes).

So if I want to access the other_struct, e.g. (other_struct*)0x200B, I would get a SIGBUS.

So I'm curious if there's a way to make GCC pad the structure to avoid this problem.

Here is the definition:

typedef struct __attribute__ ((packed)) my_packed_struct {
    uint8_t att1;
    bool att2;
    uint32_t att3;
    uint32_t att4;
    bool att5;
} my_packed_struct;

I could just add an attribute like

typedef struct __attribute__ ((packed)) my_packed_struct {
    uint8_t att1;
    bool att2;
    uint32_t att3;
    uint32_t att4;
    bool att5;
    uint8_t pad;
} my_packed_struct;

To make sure to match to size 12, but I'm looking for a solution where I wouldn't have to compute the size and pad manually (e.g. if I have to add another attribute in the future).

I had a look at memory alignment within gcc structs, I do store the struct in a buffer internally, but I still need to expose a struct for convenience and client use.

1 comments

@Anty 2017-02-15 21:34:39

What about this trick

union __attribute__ ((packed)) struct_union
{
    struct my_packed_struct data;
    int pad[(sizeof(my_packed_struct)+3)/sizeof(int)];
} struct_union;

and use struct_union instead of my_packed_struct directly?

Why it will work?

  1. union is packed so it will not be extra padded
  2. pad will always be multiple of 4 (because of int)
  3. sizeof calculation will make sure it is big enough to hold whole my_packed_struct

@M.M 2017-02-15 21:45:34

You should replace 3 with sizeof(int) - 1 (or whatever the source of 3 is)

@Anty 2017-02-15 21:50:38

Yes - 3 is sizeof(int)-1. int could be replaced there with other types too - but the question was about 4 byte alignment.

Related Questions

Sponsored Content

5 Answered Questions

[SOLVED] Is gcc's __attribute__((packed)) / #pragma pack unsafe?

  • 2011-12-19 22:28:00
  • Keith Thompson
  • 113076 View
  • 149 Score
  • 5 Answer
  • Tags:   c gcc pragma-pack

9 Answered Questions

[SOLVED] Are packed structs portable?

3 Answered Questions

[SOLVED] Why is the compiler adding padding to a struct that's already 4-byte aligned?

  • 2017-08-02 14:30:44
  • user3878723
  • 1820 View
  • 1 Score
  • 3 Answer
  • Tags:   c gcc

1 Answered Questions

C++ struct member alignment and packing requirements on ARM

1 Answered Questions

[SOLVED] Effects of __attribute__((packed)) on nested array of structures?

2 Answered Questions

Pragma Pack Ignored and __attribute__ ((aligned (2), packed)); does not have any effect

  • 2012-08-03 20:07:34
  • microb
  • 2933 View
  • 3 Score
  • 2 Answer
  • Tags:   c gcc xilinx

3 Answered Questions

[SOLVED] struct member alignment - is it possible to assume no padding

  • 2011-06-05 09:18:04
  • selbie
  • 4831 View
  • 10 Score
  • 3 Answer
  • Tags:   c++ c linux gcc

Sponsored Content