Greetings! I hope this is a right place to ask a C++ related question.
I have been following this guide: Policies/Binary Compatibility Issues With C++ - KDE Community Wiki to preserve binary stability of my classes.
I wanted the compiler to assist me to make sure that ABI is not accidentally broken when adding new bit field members. I would like you to take a look at my solution and tell me if I am doing it correctly.
The problem: suppose we have a class like this:
class Test
{
public:
bool flag1 : 1;
bool flag2 : 1;
bool flag3 : 1;
uint8_t something_else : 1;
uint8_t reserved_01 : 4;
uint8_t reserved_02 : 8;
uint16_t reserved_03 : 15;
Test ();
// Other members, PIMPL, etc.
};
And in the new version we need to add another bit field. Here is one of the possible mistakes that breaks ABI that could be made:
class Test
{
public:
bool flag1 : 1;
bool flag2 : 1;
bool flag3 : 1;
uint8_t something_else : 1;
uint8_t MISTAKE : 4; // ABI broken because we forgot to remove the reserved_01 member, class size changes.
uint8_t reserved_01 : 4;
uint8_t reserved_02 : 8;
uint16_t reserved_03 : 15;
Test ();
// Other members, PIMPL, etc.
};
This is what I came up with to prevent that from happening:
struct TestBase
{
bool flag1 : 1;
bool flag2 : 1;
bool flag3 : 1;
uint8_t something_else : 1;
uint8_t reserved_01 : 4;
uint8_t reserved_02 : 8;
uint16_t reserved_03 : 15;
TestBase () { static_assert (sizeof (TestBase) == 4, "TestBase's size is not 32 bits"); }
};
class Test : public TestBase
{
// Other members, PIMPL, etc.
};
Now the compiler raises an error if ABI is accidentally broken, preventing the disaster. Is this the correct solution? I wanted to do that without subclassing, but could not do it reliably due to compiler taking alignment into its own hands