6.3.1.4 Debugging Optimized Code

Although it is possible to do a reasonable amount of debugging at nonzero optimization levels, the higher the level the more likely that source-level constructs will have been eliminated by optimization. For example, if a loop is strength-reduced, the loop control variable may be completely eliminated and thus cannot be displayed in the debugger. This can only happen at -O2 or -O3. Explicit temporary variables that you code might be eliminated at level -O1 or higher.

The use of the -g switch, which is needed for source-level debugging, affects the size of the program executable on disk, and indeed the debugging information can be quite large. However, it has no effect on the generated code (and thus does not degrade performance)

Since the compiler generates debugging tables for a compilation unit before it performs optimizations, the optimizing transformations may invalidate some of the debugging data. You therefore need to anticipate certain anomalous situations that may arise while debugging optimized code. These are the most common cases:

In light of such anomalies, a recommended technique is to use -O0 early in the software development cycle, when extensive debugging capabilities are most needed, and then move to -O1 and later -O2 as the debugger becomes less critical. Whether to use the -g switch in the release version is a release management issue. Note that if you use -g you can then use the strip program on the resulting executable, which removes both debugging information and global symbols.