在 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)); }
| ^~~~~~~~~~~~~~~~~~~~~~~
我使用的是 MSYS 版本的 G++,版本 14.1.0。 这是一个已知的(未实现的)功能,还是我的代码中的某些功能? 这是声明的简化版本(
...
是代码片段):
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);
}
}
这似乎是 GCC 中的一个错误,可能与 Bug 114968 - [14/15 回归] 缺少
__thiscall
的内置声明中的
__cxa_thread_atexit()
属性有关(或由其引起)。
__cxa_throw
的一个声明来自于 <variant>
的投掷,看起来像 void __cxa_throw(void*, void*, void (*)(void*))
。 __cxa_throw
的另一个声明来自您的模块,看起来像 void __cxa_throw(void*, void*, void (__attribute__((thiscall)) *)(void*))
。唯一的区别是 dtor 回调(第三个参数)在模块中声明 thiscall
。
如果您使用的 GCC 版本早于该错误的修复,我会尝试升级。如果您使用的 GCC 版本已经包含该修复程序,则该修复程序很可能无法完全解决问题,这将需要一个新的错误报告。