Depends, and this is generally true of all tools not just C30.
Optimizations often remove and/or restructure the code in various ways. Your switch statement may get reimplemented with a if/else construct or in some cases may be removed all together. y = x * 16 may get replaced with a series of left shifts, etc. although this last type of optimization can usually still be stepped through, its mostly the restructuring of control statement that gets ya.
This can make it impossible to step a debugger through your C code because the structures you defined in C no longer exists, they were replaced or re-ordered by the compiler into something the compiler believes will be faster or use less space. It can also make breakpoints impossible to set from the C listing since the instruction your breaking on may no longer exist. For example you may try to set a breakpoint inside an if statement, but the compiler may have removed that if. You may try to set a breakpoint inside a while or for loop but the compiler decided to unroll that loop so it no longer exists.
For this reason if you can debug with optimizations off, its usually easier. You should always retest with optimizations on. This is about the only way you'll find out that you missed an important volatile
and its causing intermittent failures (or some other weirdness).
In the case of embedded development, you have to be careful with optimizations anyway. Specifically in sections of code that are timing critical, some interrupts for instance. In these cases you should either code the critical bits in assembly or use compiler directives to make sure these sections are not optimized so you know they have a fixed execution time or a fixed worst case run time.
The other gotcha can be fitting code into the uC, you may need code density optimizations to simply fit your code into the chip. This is one reason why its usually a good idea to start with the largest ROM capacity uC in a family and only choose a smaller one for manufacturing, after your code is locked.