如果在调试版本中打开编译器优化,会出现什么问题?

Don*_*alo 2 compiler-construction microcontroller compiler-optimization

为什么在调试应用程序时必须/建议关闭所有编译器优化?

背景

我正在使用一个8位微控制器(OKI 411),它有15K可用代码存储空间用于中断服务程序+ ROM区域/窗口(const全局变量)+代码.我们差不多吃了大约13K,所以在调试过程中打开最大可能的优化非常诱人.

Jam*_*lis 6

编译调试二进制文件时,编译器会尝试在代码语句(或代码语句)与汇编语言指令之间保持1:1的对应关系.这样,当您进行调试时,您可以逐步执行指令,并且调试器可以轻松地将其在二进制文件中的当前位置与正确的源代码相关联.通常,编译器还确保所有命名变量实际存在于内存中的某个位置,以便您可以在调试器中查看其内容.

编译器优化可能会忽略未使用或不必要的局部变量,并可能重新构建代码以使其更有效.可以内联函数,并且可以部分或全部预先计算或重新排列表达式.大多数这些和类似的优化使得难以将原始源代码与生成的程序集相关联.


Set*_*eth 5

考虑:

for (i = 0; i < 10; i++) {
    src[i] = dest[i];
}
Run Code Online (Sandbox Code Playgroud)

优化后,此代码可能如下所示:

src[0] = dest[0];
src[1] = dest[1];
?
src[9] = dest[9];
Run Code Online (Sandbox Code Playgroud)

换句话说,已经没有i了.调试器期望i在堆栈帧上,但优化器将其删除.

此外,当踩踏时,PC会跳到整个地方(显然是随机的),你会遇到各种其他的怪异,这会使调试变得非常困难或不可能(取决于优化器的作用).