If you’ve worked on a nontrivial game in C++, you’ve probably run into a situation where you’d like to step through some code in the debugger, but the debug build of your game is painfully slow and debugging in release mode is difficult and time-consuming.
Here’s something you probably know (but if you don’t, it will change your life): you can disable optimization selectively per file, and thus have access to good debug information while not crippling your performance by running in debug mode.
In the Microsoft compiler, you do it this way:
#pragma optimize("", off)
This will turn off all optimization in whatever source file you put it in. (The optimize pragma has some options to make the changes more granular, but I’ve never really had a need for that.)
There is, however, a subtle problem here: it is very easy to forget to remove that one innocuous line after adding it–and end up, in the worst case, shipping your game with optimization turned off for some files.1 It would be nice if the compiler would let us know if we forgot to remove this pragma, right?
What I do is create a no_opt.h header and include it in any files I’d like to be able to step through:
#pragma once #pragma message("no_opt.h included in " __FILE__) #ifdef _RELEASE_FINAL #error no_opt.h included in release final build; remove. #else #pragma optimize("", off) #endif
Replace _RELEASE_FINAL with whatever your “final” build configuration you release to end users–i.e. the configuration that’s build by your build system.2
With that, the compiler will spit out a message for every file that has optimizations disabled. Further, if you don’t notice the message, it will fail to compile on your final build, giving you a second chance to remove the header.
1. If you’re thinking to yourself that you’re not that forgetful and have always remembered to remove it, I’m sorry to report that you’ve almost definitely shipped code with optimizations disabled.
2. This practice may sound strange if you’re not familiar with it, but at least in game development it’s not unusual to have a “release” build and a “final release” build, where the former will disable optimizations and the latter might go further by turning off developer tools, removing symbols, etc.