C++ 防止gcc/libstdc++;从调用terminate到抛出from throw()方法

C++ 防止gcc/libstdc++;从调用terminate到抛出from throw()方法,c++,linux,exception,gcc,C++,Linux,Exception,Gcc,如果我有一个标记为throw()的方法,例如 但内部确实发生异常,gcc将终止应用程序(消息为“在抛出“xyz”实例后终止调用”) 有没有办法避免这种行为 例如,用于忽略throw()内容或强制生成eh_帧的命令行开关。等等。您可以通过调用std::set\u terminate来提供自己的终止处理程序。。。然而,我认为从那里返回是不合法的,所以它唯一能做的就是以某种方式终止 您可以为自己的意外异常处理程序提供std::set\u unexpected:默认的异常处理程序调用std::termi

如果我有一个标记为throw()的方法,例如

但内部确实发生异常,gcc将终止应用程序(消息为“在抛出“xyz”实例后终止调用”)

有没有办法避免这种行为


例如,用于忽略throw()内容或强制生成eh_帧的命令行开关。等等。

您可以通过调用
std::set\u terminate
来提供自己的终止处理程序。。。然而,我认为从那里返回是不合法的,所以它唯一能做的就是以某种方式终止


您可以为自己的意外异常处理程序提供
std::set\u unexpected
:默认的异常处理程序调用
std::terminate
,但您可以执行不同的操作(如记录和吞咽异常)。不过,恢复是否有效取决于您的程序。另外,我看到它标记为deprecated,因此依赖它可能不是最好的主意。

您可以通过调用
std::set\u terminate
来提供自己的终止处理程序。。。然而,我认为从那里返回是不合法的,所以它唯一能做的就是以某种方式终止

您可以为自己的意外异常处理程序提供
std::set\u unexpected
:默认的异常处理程序调用
std::terminate
,但您可以执行不同的操作(如记录和吞咽异常)。不过,恢复是否有效取决于您的程序。另外,我看到它被标记为不推荐,所以依赖它可能不是最好的主意。

您尝试过这个吗

-fn不强制执行eh规范

不要生成代码来检查运行时是否违反异常规范。此选项违反C++标准,但可能对减少产品结构中的代码大小很有用,就像定义“<代码> NDECHGE//COD>”一样。这不允许用户代码违反异常规范抛出异常;编译器仍然根据规范进行优化,因此引发意外异常会导致运行时出现未定义的行为

它不会强制生成EH帧,但应该停止对
std::unexpected()
的调用,因此可能对您的情况有用

正如文档所说,“编译器仍然根据规范进行优化”,例如,当调用
method()
可以内联到catch站点时,它没有帮助,因为编译器假定不需要catch,因为空的异常规范说不会抛出异常,因此,如果抛出异常,它不会被捕获。如果对
method()
的调用不可嵌入到catch站点中,则异常会在不调用
std::unexpected()
的情况下离开
method()

编辑:即使
-fn不强制eh规范
,仍将调用
std::terminate()

void func() throw() { throw ""; }
void func2() { func(); }
int main() { try { func2(); } catch (...) { } }
编译器可以看到对
func2
的调用只调用了一个no-throw函数,因此不再需要
catch
,因此进行了优化。当抛出异常时,它不会被捕获

这确实适用于
-fno强制执行eh规范
,并且不会终止:

/* func2.cc */
void func() throw();
void func2() { func(); }

/* main.cc */
void func2();
int main() { try { func2(); } catch (...) { } }
在这里,当编译
main.cc
时,编译器无法判断
func2
是否将抛出,因为它没有异常规范,并且它的定义在
main.cc
中不可见,因此不能忽略
catch
。当抛出异常时,它将被捕获。

您是否尝试了该方法

-fn不强制执行eh规范

不要生成代码来检查运行时是否违反异常规范。此选项违反C++标准,但可能对减少产品结构中的代码大小很有用,就像定义“<代码> NDECHGE//COD>”一样。这不允许用户代码违反异常规范抛出异常;编译器仍然根据规范进行优化,因此引发意外异常会导致运行时出现未定义的行为

它不会强制生成EH帧,但应该停止对
std::unexpected()
的调用,因此可能对您的情况有用

正如文档所说,“编译器仍然根据规范进行优化”,例如,当调用
method()
可以内联到catch站点时,它没有帮助,因为编译器假定不需要catch,因为空的异常规范说不会抛出异常,因此,如果抛出异常,它不会被捕获。如果对
method()
的调用不可嵌入到catch站点中,则异常会在不调用
std::unexpected()
的情况下离开
method()

编辑:即使
-fn不强制eh规范
,仍将调用
std::terminate()

void func() throw() { throw ""; }
void func2() { func(); }
int main() { try { func2(); } catch (...) { } }
编译器可以看到对
func2
的调用只调用了一个no-throw函数,因此不再需要
catch
,因此进行了优化。当抛出异常时,它不会被捕获

这确实适用于
-fno强制执行eh规范
,并且不会终止:

/* func2.cc */
void func() throw();
void func2() { func(); }

/* main.cc */
void func2();
int main() { try { func2(); } catch (...) { } }

在这里,当编译
main.cc
时,编译器无法判断
func2
是否将抛出,因为它没有异常规范,并且它的定义在
main.cc
中不可见,因此不能忽略
catch
。当抛出异常时,它将被捕获。

只有内部的catch()excheption会有帮助……所以您希望函数不能抛出异常,但能够抛出异常?我不能控制双方(也不能抛出()也不能抛出)。不是我的代码。但是我必须处理这个组合。如果必须抛出()那么你需要抓住并处理所有的问题