为什么 C/C++ 程序在调试模式下经常会关闭优化?

2022-01-17 00:00:00 c compiler-construction c++

在大多数 C 或 C++ 环境中,都有调试"模式和发布"模式编译.
查看两者之间的差异,您会发现调试模式添加了调试符号(通常是许多编译器上的 -g 选项),但它也禁用了大多数优化.
在发布"模式下,您通常会开启各种优化.
为什么会有差异?

In most C or C++ environments, there is a "debug" mode and a "release" mode compilation.
Looking at the difference between the two, you find that the debug mode adds the debug symbols (often the -g option on lots of compilers) but it also disables most optimizations.
In "release" mode, you usually have all sorts of optimizations turned on.
Why the difference?

推荐答案

没有任何优化,通过你的代码的流程是线性的.如果您在第 5 行且单步,则进入第 6 行.启用优化后,您可以获得指令重新排序、循环展开和各种优化.
例如:

Without any optimization on, the flow through your code is linear. If you are on line 5 and single step, you step to line 6. With optimization on, you can get instruction re-ordering, loop unrolling and all sorts of optimizations.
For example:


void foo() {
1:  int i;
2:  for(i = 0; i < 2; )
3:    i++;
4:  return;

在此示例中,无需优化,您可以单步执行代码并点击第 1、2、3、2、3、2、4 行

In this example, without optimization, you could single step through the code and hit lines 1, 2, 3, 2, 3, 2, 4

启用优化后,您可能会得到如下所示的执行路径:2、3、3、4 甚至只是 4!(这个函数毕竟什么都不做……)

With optimization on, you might get an execution path that looks like: 2, 3, 3, 4 or even just 4! (The function does nothing after all...)

归根结底,启用优化的调试代码可能会非常痛苦!特别是如果您有大型函数.

Bottom line, debugging code with optimization enabled can be a royal pain! Especially if you have large functions.

请注意,开启优化会更改代码!在某些环境(安全关键系统)中,这是不可接受的,被调试的代码必须是交付的代码.在这种情况下,必须通过优化进行调试.

Note that turning on optimization changes the code! In certain environment (safety critical systems), this is unacceptable and the code being debugged has to be the code shipped. Gotta debug with optimization on in that case.

虽然优化和未优化的代码在功能上"应该是等效的,但在某些情况下,行为会发生变化.
这是一个简单的例子:
<代码>

While the optimized and non-optimized code should be "functionally" equivalent, under certain circumstances, the behavior will change.
Here is a simplistic example:


    int* ptr = 0xdeadbeef;  // some address to memory-mapped I/O device
    *ptr = 0;   // setup hardware device
    while(*ptr == 1) {    // loop until hardware device is done
       // do something
    }

关闭优化后,这很简单,您也知道会发生什么.但是,如果您启用优化,可能会发生以下情况:

With optimization off, this is straightforward, and you kinda know what to expect. However, if you turn optimization on, a couple of things might happen:

  • 编译器可能会优化 while 块(我们初始化为 0,它永远不会是 1)
  • 指针访问可能会移至寄存器而不是访问内存->无 I/O 更新
  • 内存访问可能被缓存(不一定与编译器优化相关)

在所有这些情况下,行为都会大不相同,而且很可能是错误的.

In all these cases, the behavior would be drastically different and most likely wrong.

相关文章