2008 07 02Less bugs through compiler optimizations
// Get a symbol void* sym = dlsym(handle, "function1"); // Cast it to correct signature double (*fn)() = sym; // Call it fn(); // Get another symbol void* sym2 = dlsym(handle, "function2");
// Cast it to correct signature
SomeStruct (*fn2)(float, float, float) = sym2;
// Call it
fn(1, 2, 3);
// Misassign new symbol to first pointer fn = sym2; // Call uninitialized function pointer fn2(1, 2, 3);
And *BUG* ! Hmm … strange … let's try that in a Release build, one of my Stupid Voodoo Programming Tactiques, and … it works ! I stare at the code for a stupid amount of time, dumbfounded, wondering the obvious bug lies. Oh. There.
I'm getting a new function pointer but calling the former one with the new signature … oups ! I'm getting a new function pointer but assigning it to the first one, then calling that uninitialized pointer.
How come it works in Release but not in Debug ? In Debug, GCC optimizes nothing and allocates two function pointers. In Release, GCC allocates one function pointer and uses it in both calls. Therefore calling
fn(1, 2, 3) equals calling
fn2(1, 2, 3); : that's Invisible Release Build Bug.
Moral of the day : always Release builds ! :)EDIT I messed up while cleaning the code for this post. I even messed up the diagnostic, but … not the explanation ! :) To sum it up : XCode won't warn you when calling uninitialized function pointers.