g++
是使用DWARF2
,sjlj
或seh
例外模型构建的。 MinGW-builds提供具有不同异常模型的g++
的各种版本。我希望能够从gcc
工具链中确定正在使用的异常模型。是否有g++
参数将转储编译器的默认异常模型?
答案 0 :(得分:12)
编辑:最初,我正在测试g++ -v
中描述的配置标志。正如Jonathon Wakely在评论中指出的那样,不是一件好事。
执行此操作的检查方法是编译到程序集:
struct S { ~S(); };
void bar();
void foo() {
S s;
bar();
}
g++ -S <filename> -o output.s
的结果包含以下异常引用:
<强> MinGW-4.8.1-x86-posix-sjlj
强>
.def ___gxx_personality_sj0; .scl 2; .type 32; .endef
.def __Unwind_SjLj_Register; .scl 2; .type 32; .endef
.def __Unwind_SjLj_Unregister; .scl 2; .type 32; .endef
.def __Unwind_SjLj_Resume; .scl 2; .type 32; .endef
<强> MinGW-4.8.1-x86-posix-dwarf
强>
.def ___gxx_personality_v0; .scl 2; .type 32; .endef
.def __Unwind_Resume; .scl 2; .type 32; .endef
<强> MinGW-4.8.1-x64-win32-sjlj
强>
.def __gxx_personality_sj0; .scl 2; .type 32; .endef
.def _Unwind_SjLj_Register; .scl 2; .type 32; .endef
.def _Unwind_SjLj_Unregister; .scl 2; .type 32; .endef
.def _Unwind_SjLj_Resume; .scl 2; .type 32; .endef
<强> MinGW-4.8.1-x64-posix-seh
强>
.def __gxx_personality_seh0; .scl 2; .type 32; .endef
.def _Unwind_Resume; .scl 2; .type 32; .endef
<强> MinGW-4.8.1-x64-posix-sjlj
强>
.def __gxx_personality_sj0; .scl 2; .type 32; .endef
.def _Unwind_SjLj_Register; .scl 2; .type 32; .endef
.def _Unwind_SjLj_Unregister; .scl 2; .type 32; .endef
.def _Unwind_SjLj_Resume; .scl 2; .type 32; .endef
<强> FC17-g++-4.7.2-x64
强>
.cfi_personality 0x3,__gxx_personality_v0
.globl __gxx_personality_v0
call _Unwind_Resume
我们应该搜索__gxx_personality_([a-z])(0-9]+)
,然后将第一个捕获组与以下内容进行比较:
v
= dwarf
seh
= seh
sj
= sjlj
答案 1 :(得分:3)
为了补充上面的答案,GCC有一个预定义的宏,允许在编译时识别是否使用了SJLJ异常模型:
.post a:hover{ background-color:#f00; }
如果编译器使用基于setjmp和longjmp的旧机制进行异常处理,则定义此宏,值为1。
请参阅https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html
根据文档,至少从版本3.1.1开始提供;我刚刚在GCC 7.1上测试过它(在MinGW-w64下)。