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.
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.
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.
We can avoid the structure padding in C in two ways: Using #pragma pack(1) directive. Using attribute.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With