Unlike most other C compilers, GNU CC allows you to use `-g' with `-O'. The shortcuts taken by optimized code may occasionally produce surprising results: some variables you declared may not exist at all; flow of control may briefly move where you did not expect it; some statements may not be executed because they compute constant results or their values were already at hand; some statements may execute in different places because they were moved out of loops.
Many compilers (but not gcc) can use profiling information to fine-tune their optimizations. Profiling information is also useful in determining which parts of your program are worth speeding up and which parts aren't.