In the previous post, I described a “puzzler”. Here’s the brief version:
After testing the code (debug build), and verifying that it worked fine, I re-ran the code in an optimized build, just to make sure that I hadn’t inadvertently introduced any performance regressions.
Instant segfault. For every benchmark.
In sum – crashes when optimized:
- Everything works fine in debug builds.
- Complete disaster in optimized builds.
Below is a code snippet that demonstrates the problem. I had forgotten to return a value from a function (see gimme()). In unoptimized mode (as Daniel Jiménez correctly guessed), this code worked because intermediates and locals were placed on the stack. In optimized mode, they’re stashed in registers, so the pointer gets overwritten. Kudos to Tongping for tracking this bug down.
Why g++ does not generate warnings for this code without adding “-Wall” is beyond me.
Moral? Always compile with “-Wall”…
static int x = 100;
static int * xptr = &x;
void * dat (void) {
void * p = xptr;
return p;
}
void * gimme (void) {
void * p = dat();
}
int main()
{
cout << *((int *) gimme()) << endl;
return 0;
}
Yes, GCC’s warning is less strict than it should have be.
Try clang. 🙂
mikeandmore% clang test.c -Wall
test.c:13:1: warning: control reaches end of non-void function [-Wreturn-type]
}