Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
281 views
in Technique[技术] by (71.8m points)

gcc - Repacking a struct in C/C++

I would like to have a single definition for packed and unpacked structs.

The intent is to use reflection to translate one to the other. I do this currently by redefinition for performance versus wire formatting. It is necessary to have two definitions and memberwise copy between them to stop those rude segfaults.

It would be nice to not have two definitions in the spirit of DRY.

The C++ standard doesn't help which is unfortunate given how important packing is in wire formats.

I can't seem to find an implementation-defined way of doing this.

An __attribute__((packed)) within a using alias or a #pragma pack(1) wrapping the same doesn't change the packing.

I was hoping there would be some alternative to wrapping stuff in YAM (yet another macro).

FWIW adding an alignment via the using A __attribute__((aligned(256))) = UnA; does work on gcc v10.2. Changing the packing does not, sadly :-(.

Any clever trick I haven't found would be much appreciated.

--Matt.

question from:https://stackoverflow.com/questions/65856904/repacking-a-struct-in-c-c

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

It would be nice to not have two definitions in the spirit of DRY.

From a technical point of view it’s not a question of DRY. Two stucts with the same members in the same order but different padding are two distinct types. They have nothing in common because they may have different sizes and the members may live at different offsets. That’s as distinct as it gets.

So, separate definitions are unavoidable. To mitigate the source code duplication you could use the preprocessor. But you’re right of course, YAM is generally ugly, probably error prone, and altogether awful.

Instead take your preferred code generator and get rid of the duplication that way. The details depend on what that generator can do, of course. The most convenient solution for the programmer would be to write the non-packed struct manually. Something like this:

// header.hpp
namespace foo
{
struct Bar
{
    // members ...
};
}

Possibly you need some kind of tag (macro? custom annotation?) to mark the types that need a packed version. Then let the code generator parse that header (possibly using libClang/libTooling) and generate the rest:

// header_packed.hpp
namespace foo::packed 
{
struct __attribute__((packed)) Bar 
{
    // members ...
};

// conversion functions ...
}

The second best option is to write the relevant structs not in C++ but in some kind of DSL your code generator is familiar with and then generate all the C++ from that.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...