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")?
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+
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