症状
VS Code 里写了个 hello world:
#include <iostream>
using namespace std;
int main() {
cout << "Hello world!" << endl;
return 0;
}
Ctrl+Alt+N(Code Runner)→ 编译通过 → 运行崩:
[Done] exited with code=3221225477 in 1.097 seconds
退出的 3221225477 就是 0xC0000005,也就是 STATUS_ACCESS_VIOLATION——俗称段错误(segfault)。
一个 hello world 能 segfault,说明问题不在代码,在环境。
排查
第一坑:路径错了
看看编译器的实际位置:
$ ls /d/Apps/mingw64/mingw64/bin/g++.exe
结果是 MinGW-w64 15.2.0(UCRT 版本),而我 Code Runner 里配的是 D:\Apps\TDM-GCC\bin\g++.exe——一个根本不存在的目录。
嗯,之前不知道哪个助手写进记忆里的,信了。
第二坑:运行时缺 DLL
路径改对后,编译确实过了,但运行还是崩。手动跑一下试试:
$ g++ hello.cpp -o hello.exe -static-libgcc -fexec-charset=gbk
$ ./hello.exe
Segmentation fault
查一下编译产物依赖的 DLL:
$ objdump -p hello.exe | grep "DLL Name"
DLL Name: libstdc++-6.dll
DLL Name: KERNEL32.dll
DLL Name: api-ms-win-crt-environment-l1-1-0.dll
DLL Name: api-ms-win-crt-heap-l1-1-0.dll
...
看到了吧——libstdc++-6.dll。这个 DLL 在 MinGW 的 bin 目录下,但不在系统的 PATH 里。运行时找不到它,直接崩。
前面的 -static-libgcc 只处理了 libgcc 的静态链接,没管 libstdc++。
验证
分别试了几种编译方式:
| 编译选项 | 结果 |
|---|---|
| 无特殊选项 | ❌ 运行崩 |
-static-libgcc |
❌ 运行崩 |
-static-libgcc -static-libstdc++ |
✅ 正常输出 |
-static(全静态) |
✅ 正常输出 |
-static 也能解决,但编译产物体积会大很多。只加 -static-libstdc++ 就够了——把 C++ 标准库静态链接进 exe,不依赖外部的 libstdc++-6.dll。
最终方案
Code Runner 的配置改成:
"cpp": "cd $dir && D:\\Apps\\mingw64\\mingw64\\bin\\g++.exe $fileName -o $fileNameWithoutExt.exe -static-libgcc -static-libstdc++ -fexec-charset=gbk && $dir$fileNameWithoutExt.exe"
两个关键点:
-static-libgcc -static-libstdc++→ 静态链接 GCC 和 C++ 运行时,不依赖外部 DLL-fexec-charset=gbk→ 确保中文输出在 Windows 终端不乱码(UTF-8 源码 → GBK 运行时编码)
三个 C++ 项目的 .vscode/settings.json 里同理也加上了。
教训
- 信任但验证——助手写的路径要检查,TDM-GCC 变成了 MinGW-w64 我也不知道过了多久
- Code Runner 的坑——它只编译不验证运行环境,编译通过不代表能跑
- MinGW DLL 依赖——
-static-libgcc不够,要配套-static-libstdc++,要不然写再多代码还是崩在第一条cout