Following up on the last post, I finally fixed the goddamn problem. Oh and what a problem it was. You might think I’m petty for not just giving up, rolling back to the last version and forgetting about it. Well, maybe. But I wasn’t gonna let some stupid little error get the best of me. It’s what separates the men from the boys. The nerds from the geeks. The people who spend their Friday nights debugging me from the ones who have better things to do.
Like all problems, I went to absurd lengths to find the problem until eventually it was staring me right at the face and I was dumbfounded by how ridiculous it was. But I solved it. Me. All alone. My debugging beard grew a little more rugged. For the benefit of all programmers out there that might be reading this (those that don’t care feel free to ignore this), I will explain:
I had pulled every single debugger recommended out there in a desperate attempt to get to the bottom of this. Application Verifier, WinDbg, Purify, BoundsChecker, CrtCheckMemory, the works! They all pointed me to a heap corruption in the constructor that displayed the Language screen. It made no sense. How can a blank constructor cause problems? It should be something that happened before, but none of the code that came before corrupted anything. Commenting things in and out, switching things here and there, nothing seemed to fix it. In the end, none of the code had been changed since last time aside from moving #includes. How can those cause problems???
And then it hit me. These two simple harmless lines of code atop of it all:
class State;
typedef State &(State::*EventHandler)(SDL_Event *, int);
Harmless, right? Just a forward-declaration and a pointer to a member function. Nothing fancy, right? Wrong! This was the original code:
#include "State.h"
typedef State &(State::*EventHandler)(SDL_Event *, int);
You see, that one change crushed it all. By changing the #include to a forward-declaration, the class State is no longer defined, and since a pointer-to-member is different from a regular pointer, suddenly the pointer isn’t being properly allocated, any class constructor that contains it will corrupt the heap or worse and your compiler won’t so much as flinch or warn you about this. Now your program’s exploding all over the place with no code line or visible call stack or anything to grab on to and oh my gawd it’s all so horrible it just hit you out of nowhere you’re completely lost you don’t know what to do your project is dead you lost your job your house burned down your wife traded you for someone who codes Facebook applicatiions and suddenly you just find yourself lying in the streets wondering where did it all go so wrong.
And that is how I survived The Great Include War of 2010.