PAYATHON 2026

VS Code 编译 C++ 报 Exit code: -1 与 MinGW-w64 安装失败

排障赵师傅

结论

代码没有语法问题,日志反映的是两个相对独立的故障:

  1. VS Code 正在用 gcc.exe 构建 C++ 文件。链接时没有自动加载 C++ 标准库,所以出现了大量 undefined reference。这里应改用 g++.exe。
  2. MSYS2 下载软件包时连接超时或速度过低,安装事务很可能没有完成。网络恢复后,需要重新更新并安装 UCRT64 工具链,然后检查 g++.exe 是否可用。

Exit code: -1 是 VS Code 任务终止时显示的结果。判断故障原因应看前面的链接错误:

undefined reference to `std::cout'
undefined reference to `operator new(...)'
undefined reference to `__gxx_personality_seh0'
collect2.exe: error: ld returned 1 exit status

为什么会出现 undefined reference

日志中的构建命令是:

C:/msys64/ucrt64/bin/gcc.exe ... hell.cpp -o hell.exe

这里使用了 gcc.exe。

GCC 会根据 .cpp 扩展名把文件当成 C++ 源代码,因此语法检查和目标文件生成都可能成功。但由 gcc 驱动程序执行链接时,不会像 g++ 那样自动链接 C++ 标准库和相关运行库。

编译器可以识别 std::string、std::vector 和 std::cout,链接器却找不到这些符号的实现,于是报告大量 undefined reference。

C++ 程序应使用:

C:\msys64\ucrt64\bin\g++.exe

也可以为 gcc 手动添加 C++ 链接库,但通常没有必要。直接使用 g++ 更稳妥,也符合常见的配置方式。

MSYS2 下载错误是什么意思

日志中还有这些信息:

Connection timed out
Operation too slow
too many errors from mirror.msys2.org

它们表示 pacman 未能及时从 MSYS2 镜像下载软件包。可能的原因包括网络不稳定、镜像暂时不可用、代理或防火墙限制,或者连接该镜像的线路速度过低。

too many errors ... skipping for the remainder of this transaction 表示某个镜像连续失败后,pacman 在当前事务中暂时跳过了它。这不是编译器错误。

仅凭这些日志片段,无法确定整个工具链已经损坏,因为 pacman 后续仍可能从其他镜像成功下载。不过,日志显示多个镜像都失败了,这次安装事务很可能没有完成。编译输出又说明 gcc.exe 和 C++ 头文件已经存在,因此也可能是之前安装过部分组件,或者本次升级中途失败。

重新安装并检查工具链

打开开始菜单中的 MSYS2 UCRT64 终端。不要在普通 MSYS、MINGW32 或其他环境中混用这套命令。

先更新系统:

pacman -Syu

如果终端提示关闭窗口,请按提示操作。随后重新打开 MSYS2 UCRT64,再次执行:

pacman -Syu

更新完成后,重新安装 UCRT64 工具链:

pacman -S --needed mingw-w64-ucrt-x86_64-toolchain

如果下载仍然超时,可以尝试以下方法:

  • 稍后重试,确认是否只是镜像临时故障。
  • 换用更稳定的网络。
  • 检查代理、防火墙或安全软件是否阻止了 pacman.exe。
  • 按照 MSYS2 的镜像配置说明更换镜像,或调整镜像顺序。
  • 如果连接能够建立,但总因速度过低而超时,可以在 /etc/pacman.conf 的 [options] 部分临时加入:
DisableDownloadTimeout

这个配置只能取消低速超时判断,无法解决网络完全不可达的问题。安装结束后可以将其删除。

不要混用 /ucrt64、/mingw64 和其他环境的软件包。当前路径是 C:\msys64\ucrt64\bin,对应的软件包前缀应为:

mingw-w64-ucrt-x86_64-

验证安装是否完整

在 MSYS2 UCRT64 终端中运行:

pacman -Q mingw-w64-ucrt-x86_64-gcc
g++ --version
which g++

正常情况下,which g++ 应指向:

/ucrt64/bin/g++

还可以检查已安装软件包是否缺少文件:

pacman -Qkk mingw-w64-ucrt-x86_64-gcc

在 Windows PowerShell 或 cmd.exe 中执行:

where gcc
where g++

确认 VS Code 最终使用的是:

C:\msys64\ucrt64\bin\g++.exe

如果 where 返回了多套 GCC,请调整 PATH 的顺序,或者在 VS Code 配置中填写完整路径,以免选中旧版本或其他 MinGW 环境中的编译器。

先在终端直接测试

进入源文件所在目录,执行:

C:\msys64\ucrt64\bin\g++.exe -std=c++17 -g hell.cpp -o hell.exe

然后运行程序:

.\hell.exe

预期输出为:

Hello C++ World from VS Code and the C++ extension!

如果这条编译命令能够成功执行,说明工具链可以正常工作,接下来只需修正 VS Code 的构建任务配置。

修改 VS Code 的构建任务

当前任务名称是:

C/C++: gcc.exe build active file

可以重新选择 g++.exe,也可以直接修改项目中的 .vscode/tasks.json:

{
    "version": "2.0.0",
    "tasks": [
        {
            "type": "cppbuild",
            "label": "C/C++: g++.exe build active file",
            "command": "C:\\msys64\\ucrt64\\bin\\g++.exe",
            "args": [
                "-fdiagnostics-color=always",
                "-std=c++17",
                "-g",
                "${file}",
                "-o",
                "${fileDirname}\\${fileBasenameNoExtension}.exe"
            ],
            "options": {
                "cwd": "${fileDirname}"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            }
        }
    ]
}

保存后执行 Terminal → Run Build Task,确认终端第一行显示:

C:/msys64/ucrt64/bin/g++.exe

不应再显示:

C:/msys64/ucrt64/bin/gcc.exe

如果命令面板中仍保留旧任务,可以运行 C/C++: Edit Configurations (UI),或者重新执行 C/C++: g++.exe build and debug active file,然后选择 UCRT64 目录中的 g++.exe。

保持 IntelliSense 配置一致

建议将 .vscode/c_cpp_properties.json 中的 compilerPath 也设为:

{
    "configurations": [
        {
            "name": "Win32",
            "compilerPath": "C:\\msys64\\ucrt64\\bin\\g++.exe",
            "cppStandard": "c++17",
            "intelliSenseMode": "windows-gcc-x64"
        }
    ],
    "version": 4
}

compilerPath 主要影响 IntelliSense、头文件搜索和代码提示。实际构建时使用哪个编译器,由 tasks.json 中的 command 决定。只修改 IntelliSense 配置,无法解决当前的链接错误。

程序代码

原代码不会导致这些链接错误。可以整理一下格式,并显式返回 0:

#include <iostream>
#include <string>
#include <vector>

using namespace std;

int main()
{
    vector<string> msg {
        "Hello",
        "C++",
        "World",
        "from",
        "VS Code",
        "and the C++ extension!"
    };

    for (const string& word : msg)
    {
        cout << word << " ";
    }

    cout << endl;
    return 0;
}

C++ 允许 main 在末尾隐式返回 0,所以原代码没有写 return 0; 并不是本次失败的原因。

用户名和项目路径中虽然包含西里尔字符,但日志显示编译器已经成功读取源文件并生成临时目标文件。因此,这次错误也不是由非 ASCII 路径直接引起的。

建议先让 pacman 完成 UCRT64 工具链的安装,再确认 g++ --version 能够正常执行,最后将 VS Code 的构建命令从 gcc.exe 改为 g++.exe。

备注:内容仅供参考。