samedi 18 janvier 2020

Is there any portable way to ensure a struct is defined without padding bytes using c++11?

Lets consider the following task: My C++ module as part of an embedded system receives 8 bytes of data, like: uint8_t data[8]. The value of the first byte determines the layout of the rest (20-30 different). In order to get the data effectively, I would create different structs for each layout and put each to a union and read the data directly from the address of my input through a pointer like this:

struct Interpretation_1 {
    uint8_t multiplexer;
    uint8_t timestamp;
    uint32_t position;
    uint16_t speed;
};
// and a lot of other struct like this (with bitfields, etc..., layout is not defined by me :( )

union DataInterpreter {
    Interpretation_1 movement;
    //Interpretation_2 temperatures;
    //etc...
};

...
uint8_t exampleData[8] {1u, 10u, 20u,0u,0u,0u, 5u,0u};
DataInterpreter* interpreter = reinterpret_cast<DataInterpreter*>(&exampleData);
std::cout << "position: " << +interpreter->movement.position << "\n";

The problem I have is, the compiler can insert padding bytes to the interpretation structs and this kills my idea. I know I can use

  • with gcc: struct MyStruct{} __attribute__((__packed__));
  • with MSVC: I can use #pragma pack(push, 1) MyStruct{}; #pragma pack(pop)
  • with clang: ? (I could check it)

But is there any portable way to achieve this? I know c++11 has e.g. alignas for alignment control, but can I use it for this? I have to use c++11 but I would be just interested if there is a better solution with later version of c++.

Aucun commentaire:

Enregistrer un commentaire