Mingw编译的程序乱设置优化参数-O2导致的运行时崩溃问题

⌚Time: 2025-06-18 16:35:00

👨‍💻Author: Jack Ge

我的gtk程序在从debug模式切换到release模式后,运行文件扫描,之后崩溃。但是debug模式就不会崩溃。

我先是在程序里加了一些测试语句,输出,发现是在一个回调函数执行的时候导致崩溃

std::cout<<"info 1\n";
callback_function();
std::cout<<"info 2\n";

只打印了info 1,没有打印info 2

就进入哪个回调函数,在这个函数里加了测试输出语句,我发现这个回调函数在执行结束后依旧没有任何问题,是正常输出了测试语句然后退出的。我就不知道是什么原因了。

void function(){
std::cout<<"info a\n";
...
std::cout<<"info b\n";
...
std::cout<<"info c\n";//执行完这个语句代表正常结束退出
}

调用它的地方执行失败,但是它本身执行完成了。输出是这种

info 1
info a
info b
info c

我测试了回调函数指针也不是空指针。

后来我就想,Mingw并不区分debug和release模式,只不过是编译参数的区别,我检查了IDE的编译参数,发现debug版本有的编译参数和release版本的区别就是,debug版本多了这两个参数:-g3 -D__DEBUG__

release版本多了这个参数:-O2,这是一个优化参数,我尝试去掉-O2参数,发现运行就不崩溃了。

-O2会更激进的优化代码,根据我的理解就是使用这个参数后编译器认为你的代码写的非常合理,不会导致一些未定义行为,就极端优化掉一些代码。导致造成解引用空指针之类的问题。

就比如

#include <stdio.h>

int main() {
    int *p = NULL;
    int x = (p != NULL) ? *p : 0;  // 潜在空指针解引用
    printf("%d\n", x);
    return 0;
}
//-O0:可能侥幸运行(未实际解引用)。
//-O2:直接优化掉条件判断,导致段错误。

(1) -O0(无优化)

(2) -O2(激进优化)


所以我这种编程没有太规范的人还是老老实实用-O0吧。