Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C(++) struct force extra padding

I've seen countless questions of the form "I don't like padding how do I turn it off", but have yet to find anything about forcing the compiler to provide extra padding.

The specific case that I have looks like

struct particle{
  vect2 s;
  vect2 v;
  int rX;
  int rY;
  double mass;
  int boxNum;
};

Where vect2 is a simple struct {double x; double y;} vect2. In order to use SSE2, I need to be able to load a pair of doubles, aligned to 16 byte boundaries. This used to work, until I added the extra int, pushing my struct size from 48 bytes to 56 bytes. The result is segfaults.

Is there some kind of compiler directive I can use that either says "pad this struct to make it a multiple of 16 bytes long", or "this struct has an alignment of 16-bytes"? I know I could do it manually (tacking on an extra char[12], for example), but I'd really rather just tell the compiler(GCC, preferably ICC compatible), and not have to do it manually if I change the struct in future.

like image 370
zebediah49 Avatar asked Jun 22 '12 16:06

zebediah49


People also ask

How do you add padding to a structure?

The compiler will insert a padding byte after the char to ensure short int will have an address multiple of 2 (i.e. 2 byte aligned). The total size of structa_t will be sizeof(char) + 1 (padding) + sizeof(short), 1 + 1 + 2 = 4 bytes. The first member of structb_t is short int followed by char.

How does padding work in C struct?

Structure Padding in C:The structure padding is automatically done by the compiler to make sure all its members are byte aligned. Here 'char' is only 1 byte but after 3 byte padding, the number starts at 4 byte boundary. For 'int' and 'double', it takes up 4 and 8 bytes respectively.

How can structure padding be avoided?

We can avoid the structure padding in C in two ways: Using #pragma pack(1) directive. Using attribute.

What is __ attribute __ packed in C?

4.11 The __packed__ Attribute This attribute, attached to struct or union type definition, specifies that each member (other than zero-width bitfields) of the structure or union is placed to minimize the memory required. When attached to an enum definition, it indicates that the smallest integral type should be used.


1 Answers

You can nest two structures to pad it automatically without needing to keep track of the size yourself.

struct particle
{
    // ...
};

{
    particle p;
    char padding[16-(sizeof(particle)%16)];
};

This version unfortunately adds 16 bytes if the structure is already a multiple of 16. It's unavoidable because the standard doesn't allow arrays of zero length.

Some compilers do allow zero length arrays as an extension, and in that case you can do this instead:

struct particle_wrapper
{
    particle p;
    char padding[sizeof(particle)%16 ? 16-(sizeof(particle)%16) : 0];
};

This version does not add any bytes of padding if the structure is already a multiple of 16.

like image 71
Mark Ransom Avatar answered Oct 08 '22 01:10

Mark Ransom