You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++模块自定义异常报错:__cxa_throw声明冲突

在MSYS G++ 14.1.0中使用C++模块自定义异常时的冲突错误

我使用MSYS版本的G++ 14.1.0开发,在C++模块中定义自定义异常类时触发了如下编译错误:

C:/Sync/Engine/Chorus/Base/win_9x.cpp:600:59: error: conflicting declaration of C function 'void __cxa_throw(void*, void*, void (__attribute__((thiscall)) *)(void*))'
  600 |                 throw Crash(Win9xErrorCode::BAD_MAIN_CLASS);
      |                                                           ^
In file included from C:/msys64/mingw32/include/c++/14.1.0/bits/version.h:49,
                 from C:/msys64/mingw32/include/c++/14.1.0/variant:36,
of module C:/msys64/mingw32/include/c++/14.1.0/variant, imported at C:/Sync/Engine/Chorus/Base/error.cppm:16,
of module Error, imported at C:/Sync/Engine/Chorus/Base/win_9x.cpp:217:
C:/msys64/mingw32/include/c++/14.1.0/variant:1349:5: note: previous declaration 'void __cxa_throw(void*, void*, void (*)(void*))'
 1349 |   { _GLIBCXX_THROW_OR_ABORT(bad_variant_access(__what)); }
      |     ^~~~~~~~~~~~~~~~~~~~~~~

想请教这是G++的已知未实现特性,还是我的代码存在问题?

以下是简化后的异常类模块代码(...为省略内容):

export module Error;

...

enum class ErrorType: uint8_t {
    ...
};
export enum class Win9xErrorCode: uint16_t {
    ...
};
export enum class WinXPErrorCode: uint16_t {
    ...
};

export class Crash: public std::exception {
    public:
        Crash(Win9xErrorCode crashCode) noexcept: code(crashCode), type(ErrorType::WIN9X) { }
        Crash(WinXPErrorCode crashCode) noexcept: code(crashCode), type(ErrorType::WINXP) { }

    private:
        std::variant<Win9xErrorCode, WinXPErrorCode, Win7ErrorCode> code;
        ErrorType type;
};

触发报错的代码位于非模块文件中:

void setupMainWindow(...) {
    WNDCLASSEX graphicsWindowClass = {
        ...
    };
    if(!RegisterClassEx(&graphicsWindowClass)) {
        throw Crash(Win9xErrorCode::BAD_MAIN_CLASS);
    }
}

问题原因及解决方案

这是MinGW G在C模块场景下的已知ABI兼容性问题,不属于你的代码逻辑错误。

错误核心是__cxa_throw函数的声明冲突:

  • 从C++模块中导入std::variant时,编译器生成的__cxa_throw声明带有thiscall调用约定修饰
  • 而标准库头文件中原本的__cxa_throw声明无此修饰,导致编译阶段出现冲突

临时修复方案:

  • 调整std::variant的使用场景:将std::variant的代码移到非模块文件中,或者改用其他方式存储错误码(比如为不同系统错误定义独立的异常子类)
  • 升级MinGW版本:后续更新的MSYS2 MinGW包可能已修复该模块与标准库的调用约定冲突问题
  • 改用传统头文件结构:如果C++模块不是必需的,将Error模块改为普通头文件+源文件的形式,可直接避开此问题

补充说明:

该问题与你自定义的Crash异常类逻辑无关——哪怕移除std::variant成员,只要在模块中导入部分标准库组件(如std::variant),在非模块代码中抛出异常就可能触发冲突,本质是MinGW的C++模块实现仍存在ABI层面的不完善。

内容的提问来源于stack exchange,提问作者Warpspace

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 17:53:16