3
votes

Giving simple structure (POD) containing only one array of shorts (bytes, ints from <cstdint>, etc) and no more fields will be added later:

#define FIXED_SIZE 128 // 'fixed' in long term, shouldn’t change in future versions
struct Foo {
    uint16_t bar[FIXED_SIZE];
};

is it any possibility to end up with padding at the end of the structure added by compiler for any reason ?

It seems reasonable not to make any padding as it is no any obvious need of it, but is it any guarantees by standard (could you provide any links where it is explained)?

Later I would like to use arrays of Foo structs in simple serialization (IPC) within different platforms and don't want to use any libraries for this simple task (code simplified for demonstration):

#define FOO_ELEMS 1024
...
// sender
Foo *from = new Foo[FOO_ELEMS];
uint8_t *buff_to = new uint8_t[FOO_ELEMS * FIXED_SIZE * sizeof(uint16_t) ];
memcpy(buff_to, from, ...);
...
// receiver
uint8_t *buff_from = new uint8_t[ ... ];
Foo *to = new Foo[FOO_ELEMS];
memcpy(to, buff_from, ...);

I would like to use struct here instead of plain arrays as it will be some auxiliary methods within struct and it seems more convenient then to use plain functions + arrays pointers instead.

Intersects with this (plain C) question, but seems a little bit different for me: Alignment of char array struct members in C standard

2
Note that for (un)serialization, you have to manage endianness. - Jarod42
You could always add a static_assert(sizeof(Foo) == FIXED_SIZE * sizeof(uint16_t), "Unexpected padding"); - Jarod42
@Jarod42 yes, this is solution I was thinking about, just want to recall before implementation, that may be (suddenly) it is well defined in standard already, but can't imaging the reasons 'why'. Also, it will be a grand surprise and karma devastating, if some maintainer will get such an error someday. - Alex Karev

2 Answers

2
votes

The various standards provide for padding to occur (but not at the start). There is no strict requirement at all that it will only appear to align the members and the object in arrays.

So the truly conformant answer is:

Yes, there may be padding because the compiler can add it but not at the start or between array elements.

There is no standard way of forcing packing either.

However every time this comes up and every time I ask no one has ever identified a real compiler on a platform that pads structures for any other reason than for internal alignment and array alignment.

So for all know practical purposes that structure will not be packed on any known platform.

Please consider this yet another request for someone to find a real platform that breaks that principle.

0
votes

Since we are already guaranteed that there will no padding at the beginning of the structure don't have to worry about that. At the end I could see padding being added if the sizeof of the array was not divisible by the word size of the machine.

The only way I could get any padding to be added to the struct though was to add an int member to the struct as well. In doing so the struct was padded to make them the same size.

#include <iostream>
#include <cstdint>

struct a
{
    uint16_t bar[128];
};

struct b
{
    uint16_t bar[127];
};

struct c
{
    int test;
    uint16_t bar[128];
};

struct d
{
    int test;
    uint16_t bar[127];
};

struct e
{
    uint16_t bar[128];
    int test;
};

struct f
{
    uint16_t bar[127];
    int test;
};



int main()
{
    std::cout << sizeof(a) << "\t" << sizeof(b) << "\t" << sizeof(c) << "\t" << sizeof(d) << "\t" << sizeof(e) << "\t" << sizeof(f);
}

Live Example