UPDATE: I am not asking people to try this out & see if the code works for them. I am asking whether the code pattern is legal C++, regardless of whether it works for you.
I am investigating what I believe is a bug in the IAR C++ compiler for Renesas RX CPUs. Examples of the following code pattern sometimes work on my small embedded system, other times it crashes during initialization of parentRefToChildInstance
in a jump to address 0x00000000 (or nearby; I've seen a jump to 0x00000038 as well). For a given version of the source code the behavior seems to be consistent between compilations, but if the code is perturbed in seemingly irrelevant ways, sometimes the behavior switches.
Is it legal to have pure-virtual-parent-class references to statically-allocated child class objects, or is it not legal because the order of initialization of statically allocated objects cannot be guaranteed?
char aGlobalVar = 0;
struct parent
{
virtual ~parent() {}
virtual void method1() = 0;
};
struct child : public parent
{
child(int someValue) : m_someData(someValue) {}
virtual ~child() {}
virtual void method1() { ++aGlobalVar; }
int m_someData;
};
child childInstance(0x1234abcd);
parent &parentRefToChildInstance = childInstance;
In cases where the crash occurs, the child class object has not been constructed at the point that the parent-class reference is initialized; I'm suspecting the compiler is somehow using the child object's vtable pointer to initialize the parent-class reference, though I haven't confirmed that for certain. But I thought the compiler should be able to initialize a reference knowing only the type of object it's referencing, and its address, both of which should be known at compile-time and link-time, respectively. If that's true, then it seems like it should not matter which order childInstance
and parentRefToChildInstance
are initialized.
Also, we're still limited to C++03, if that matters.
Here's a main()
to go along with the above code...
int main()
{
printf("aGlobalVar = %u\n", aGlobalVar);
childInstance.method1();
printf("aGlobalVar = %u\n", aGlobalVar);
parentRefToChildInstance.method1();
printf("aGlobalVar = %u\n", aGlobalVar);
}
Normally I would expect it to print this, not crash during static object initialization (even before main()
starts):
aGlobalVar = 0
aGlobalVar = 1
aGlobalVar = 2