powerpete
powerpete

Reputation: 3052

Automatic Compare Layout of 2 Structs in C++

2 structs came from different header files from different libraries. The libraries have a lot of similar stuff.

How can I ensure that the memory layout of them are binary compatible? In addition how can I check the naming of them are equal? The checking should be done at compile time.

As an example:

//Header of Library A
namespace LibA {
  struct Item {
    uint32_t A;
    uint8_t B;
    uint8_t pad1,pad2,pad3;
  };
  void FunctionOfLibA(Item *a);

}


//Header of Library B
namespace LibB {
  struct Item {
    uint32_t A;
    uint8_t B;
    uint8_t pad1,pad2,pad3;
  };
  void FunctionOfLibB(Item *a);
}

//My Usage
LibA::Item item;
LibA::FunctionOfLibA(&item);
LibB::FunctionOfLibB((LibB::Item*)(void*)(&item)); //I want to check if this cast is safe.
//So I have to ensure the alignment, pack, order etc. are the same for both LibB::Item and LibA::Item

Ok - in the above example it's easy to do it the manual way with sizeof(...) and offsetof(...). As an alternative I Can manually check the header files for each new library version.

But the question is to do it in an automatic way like static_assert(issame(LibA::Item,LibB::Item),"Check")?

Upvotes: 4

Views: 502

Answers (1)

phuclv
phuclv

Reputation: 41805

In C++20 there are the layout-compatibility and pointer-interconvertibility traits so you can do it with std::is_layout_compatible

static_assert(std::is_layout_compatible_v<LibA::Item, LibB::Item>, "Check")

Demo on Godbolt

Note that it may not work if the structs aren't standard-layout, or using non-compatible types, for example if one uses signed char/unsigned char and the other uses char (when char is signed/unsigned on that platform respectively) then they're incompatible

If your C++ version is older than that, sorry you'll have to upgrade or find another way, like modifying the 2 libraries or manually using sizeof and offsetof. However if you don't need portability then on some compilers you can try to use their intrinsics, for example __is_layout_compatible on GCC 12+

Upvotes: 2

Related Questions