In my code I have a system as outlined by the following code:
// Base class to make derived objects polymorphic
struct Base {
virtual ~Base() = default;
};
void registerData(int*) {}
template <typename Derived>
struct RegisterMixin {
static int (Derived::*dataPtr); // Defined for each derived class
RegisterMixin() {
auto* derived = static_cast<Derived*>(this);
registerData(&(derived->*dataPtr));
}
};
struct MyDerived: Base, RegisterMixin<MyDerived> {
int myData; // Will be set by the enclosing system
};
template <>
int MyDerived::*RegisterMixin<MyDerived>::dataPtr = &MyDerived::myData;
int main() {
MyDerived derived;
}
The indent is that whenever an object derived from RegisterMixin
is constructed, its data member will be registered in a global map so it can be controlled by an enclosing system.
If I run the program with UB sanitizer it complains about the static_cast<Derived*>
in the RegisterMixin
constructor that the object is not of type Derived
. I assume the error is justified because the RegisterMixin
constructor runs before the Derived
constructor.
However I don’t actually do anything with the derived object, I only access its address. Is there any way to achieve what I’m trying here without invoking UB?
https://godbolt.org/z/YK8dKc47W