【问题标题】:Can I throw exceptions through functions compiled w/o exceptions我可以通过没有异常编译的函数抛出异常吗
【发布时间】:2022-01-02 23:14:39
【问题描述】:

让我们有两个库:libA.alibB.a。他们是有组织的。 libA.a 调用 libB.a 函数并为其自身提供回调。换句话说,以下调用堆栈是可能的:

#0 liba_callback()
#1 libb_function()
#2 liba_function()

libA.a-fexceptions 编译,libB.a-fno-exceptions 编译。

问题是:如果liba_callback() 抛出,会发生什么?我可以在liba_function() 处理这个吗?我可以通过没有异常编译的函数抛出异常吗?是否定义了这种行为?

【问题讨论】:

  • 稍微回避一下这个问题:即使你能做到,也不应该因为分配的资源。鉴于 libB 不支持异常,它不会优雅地处理它们,不会调用清理代码并因此泄漏资源。
  • C++ 标准未定义该行为。异常是语言的一部分,因此不支持异常 (-fno-exceptions) 的编译器不符合语言定义。编译器可能有一些文档来解释在这种情况下会发生什么。

标签: c++ exception


【解决方案1】:

正如@Pete Becker 所说,异常是语言的一部分,因此编译器负责记录此类 C++ 方言。

GCC documentation 说:

在详细介绍库对 -fno-exceptions 的支持之前,首先要说明一下使用此标志时丢失的内容:无论该代码是否有任何代码,它都会破坏尝试通过使用 -fno-exceptions 编译的代码的异常尝试或捕获构造。如果您可能有一些抛出的代码,则不应使用 -fno-exceptions。如果你有一些使用 try 或 catch 的代码,你不应该使用 -fno-exceptions。

特别是,在没有展开信息的情况下命中堆栈帧是有问题的:

特别是,展开到没有异常处理数据的帧将导致运行时中止。如果展开器在找到处理程序之前用完展开信息,则调用 std::terminate()。


总结一下:

问题是:如果 liba_callback() 抛出,会发生什么?

abort() 被调用。

我可以在 liba_function() 中处理这个吗?

没有。

我可以通过编译没有异常的函数抛出异常吗?

没有。

这种行为是否已定义?

没有。它仅记录为编译器扩展。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-20
    • 1970-01-01
    相关资源
    最近更新 更多