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
相关产品推荐
相关产品推荐

