Okay... this is... one hell
of a Heisenbug.
- There is a class A.
- There is a class B : A with a field "color".
- There is a virtual method B::draw() which runs some time after the object is created, which reads "color". It works.
- But then I add a new data member to A, an object. Abruptly, B::draw() stops working, when it reads "color" it shows strange values usually equal to 0. The result is the left half of the screen here, which is supposed to be a field of cyan:
So, the heisenbug! I look at this and go: Ok, lots of ways this could happen, memory corruption, whatever. So I try adding some printfs to right after B b = new B(); is allocated:
- I print b->color. It prints out as the correct color.
- I call a method B::alrg(), a virtual method with its method body in one of my cpp files. It prints out as the correct color.
- I call a method B::blrg(), a virtual method with its method body in the header file. It prints out a crazy incorrect color that looks like the "mostly 0s" in the image above.
- I call a method B::clrg(), a nonvirtual method with its method body in the header file. It prints out as the correct color.
What on earth
Increasingly starting to feel conscious of exactly how much of the time I spend writing C++ software, I spend debugging problems like this.
EDIT: ...I change draw(), instead of reading this->color directly, to call this->rightcolor(), a method which returns color and whose body lives in a different file. Suddenly it draws correct colors. Working out elaborate conspiracy theories in my head where draw() is getting inlined when it's called (should be impossible?) and that the common element to the methods on B which misread the color field is that they're inlined... this sounds like nonsense.
I want to take one of the minor workarounds I've found and settle for that, but I'm terrified this bug is going to rear its head in a more destructive manner later.