这看起来是顺理成章,但是这一过程隐藏着很多危险。当你从调试版本转换到发布版本时,你应该格外的小心。现在让我们看看为什么引起注意的几个范例。
完全优化编译之后的代码有助于使之进行更快。但很多嵌入的软件和硬件在本质上是紧密相连的,所以运行速度提高只是意味着不同的调速。
比如,程序中有一个硬件装置,这一硬件在运行过程中需要一个短时间的延迟。偶尔,未经过优化的代码运行很慢以致可以避免这一题问。但是编译之后的发布代码运行速度很快,不会将这一时间延迟表现出来。
这是客观存在的事实,即编译器也可以生成错误代码。嵌入编译器更是令人讨厌:一些微妙的错误让人防不胜防。
当你建立一个优化之后的发布版本,编译器可以更紧凑更敏锐地执行源代码,所以你可以有可能碰到更多的bugs。
如果你从编译代码中调用汇编程序代码,那么汇编程序代码必须遵循基本的调用规则。这些规则指定了汇编代码可以更改哪些注册器,而哪些注册器不能更改。这些规则能够让编译器安全的保护好注册器中的变量。
然而,当生成未优化的调试代码,编译器将把变量保存在系统的堆栈中,所以对于调试器,变量是可见的。汇编程序代码不会被规则所限制。
当你要建立一个优化的发布版本,编译器就把变量保存在注册器中。汇编程序代码有时候会使程序中的变量发生混乱。
在以前的编程中,你一定会编写过内存映射I/O口,或者在一个中断处理中调用一个变量的代码。你一定已经忘记使用可变关键字的方法——这一方法很容易忘记。在调试过程中运行很好的代码,当在发布版本中运行时,就会出现很多问题,特别是束缚于注册器的循环中。或者有时候程序呆得很呆板,它们也常常被限制于一个死循环。
经过优化之后的发布版本代码变得更加简洁和紧凑,但这也意味着代码和数据在内存中已经发生了位置的变化。例如,外部RAM中原来的数据已经转移到内部CPU RAM中,或者,它已经从快SRAM转移到慢DRAM,并且硬件-软件的相互作用是不相同的。
比如,代码中有一个bug,这一bug能偶尔地操作任意内存的位置。在调试版本中,以上的bug只发生在受误用的内存位置,没有表现出很大的危害。但在发布版本中,一些重要的数据结构都会占用内存,这一bug会导致系统冲突。