Debugging Optimized Code
When the compiler optimizes code, it repositions and reorganizes instructions, resulting in more efficient compiled code. Because of this rearrangement, the debugger cannot always identify the source code that corresponds to a set of instructions. For this reason, you should do your debugging using an unoptimized version of your program if at all possible. By default, optimization is turned off in the Debug configuration of a Visual C++ program and turned on in the Release configuration.
Sometimes, however, a bug may appear only in an optimized version of a program. In that case, you must debug the optimized code.
To turn on optimization in a Debug build configuration
- When you create a new project, select the Win32 Debug target. Use the Win32 Debug target until your program is fully debugged and you are ready to build a Win32 Release target. The compiler does not optimize the Win32 Debug target.
- Select the project in Solution Explorer.
- On the View menu, click Property Pages.
- In the Property Pages dialog box, make sure Debug is selected in the Configuration drop-down list box.
- In the folder view on the left, select the C/C++ folder.
- Under the C++ folder, select Optimization.
- In the properties list on the right, find Optimization. The setting next to it probably says Disabled (/Od). Choose one of the other options (Minimum Size (/O1), Maximum Speed (/O2), Full Optimization (/Ox), or Custom).
- If you chose the Custom option for Optimization, you can now set options for any of the other properties shown in the properties list.
When debugging optimized code, look at the Disassembly window to see what instructions are actually created and executed. When setting breakpoints, you need to be aware that the breakpoint may move along with an instruction. For example, consider the following code:
for (x=0; x<10; x++)
Suppose you set a breakpoint at this line. You might expect the breakpoint to be hit 10 times, but if the code is optimized, the breakpoint is only hit once. That is because the first instruction sets the value of
x to 0. The compiler recognizes that this only has to be done once and moves it out of the loop. The breakpoint moves with it.
The instructions that compare and increment
x remain inside the loop. When you view the Disassembly window, the step unit is automatically set to Instruction for greater control, which is useful when stepping through optimized code.