结构体系进化的重要标志之一,曾经是编译器的优化。您可能还记得有些人把“RISC”缩写调侃为“Relegate the Impossible Stuff to the Compiler”,即“把不可能完成的任务丢给编译器”。然而,在调试时,一个太过自我聪明的编译器其问题也是显而易见的。比如PIC32 的“C”编译手册有提到说,当调试经过优化的代码时“可能偶尔会碰到令人惊讶的结果。”
例如,有些变量和代码会消失,如果编译器认为你其实并不需要它们。举例说你声明了一个变量,然后给它赋值一个常数,接着在某个计算时调用了这个变量。不要为找不到那个变量和赋值语句而抓狂,编译器只是比你更聪明一点,它在计算中直接调用了常数。
当你在一个条件分支指令处点击了单步执行,然后看到光标移动到了下一条指令处,这是否意味该条件分支的条件未被满足呢?未必,请注意这是MIPS 架构的一个特性,即分支指令的下一条指令总是会被执行,当编译器找不到合适的指令时会填充一条NOP 指令。你必须再执行一次单步操作,才能确认分支条件是否被满足(在这种情况下,你会看到光标跳到分支目标处)或不满足(光标跳转到下一条顺序指令)。更先进的“代码移动”优化能够导致更多的优化干预。请记住,有时指令可以被挪动很远的距离,甚至超出你认为应在的循环之外。
不过,调试优化过的代码也是可能的,尤其是你喜欢头脑风暴的话(例如,在分支指令后跟一个分支指令会发生什么?)。通常缺省的编译器优化只生成简单的代码,会完整保留你的意图即使可能它效率底下。当调试时在断点触发处,,你可以放心地修改某个变量的值,而不用担心编译器会捣什么鬼(比如虽然你从源代码中看不到,但一些赋值语句已经被挪动并执行了)。