【问题标题】:How can LLVM use C++'s standard containers without exceptions?LLVM 如何无一例外地使用 C++ 的标准容器?
【发布时间】:2016-07-30 12:07:41
【问题描述】:

根据LLVM Coding Standards,“LLVM 不使用 [...] 异常”。但是,LLVM 确实使用了 C++ 的标准容器,例如 std::vector

LLVM 怎么可能毫无例外地使用标准容器?它如何处理容器通常throw 的情况?比如std::vector::push_back不能分配内存也不能throw std::bad_alloc会怎样?

【问题讨论】:

  • 它在引用中说它会关闭它们,这可以通过 -fno-rtti 或 -fno-exceptions 轻松完成。

标签: c++ exception exception-handling stl llvm


【解决方案1】:

LLVM 将达到会引发异常的状态视为立即崩溃。如果使用的实现/编译设置启用异常,则会抛出一个展开并找到没有捕获处理程序并调用std::terminate。如果实现/编译设置禁用异常,则实现必须提供一些替代行为。大多数会立即以一种或另一种方式崩溃。

LLVM 上的开发人员使用这些设置测试他们的代码,并小心避免可能引发的情况。

无法直接避免的一种情况是分配失败。 LLVM 根本不支持分配可能失败且用户必须捕获bad_alloc 的平台。如果平台在任何时候未能分配内存,LLVM 就会崩溃。

事实证明,当今绝大多数非嵌入式平台都使用某种形式的overcommit。而且由于 LLVM 的设计方式,我们没有特别有用的机制可以优雅地响应分配内存的失败。因此,它被认为是致命且不可恢复的错误,无论我们是否启用异常,我们都将在此时终止进程。

【讨论】:

    【解决方案2】:

    libc++ 实现包含对_LIBCPP_NO_EXCEPTIONS 的检查,这是从编译器对异常的支持推导出来的。

    如果我看一下向量的具体实现,它看起来像是断言了条件而不是抛出异常。但是,我无法为bad_alloc 验证这一点。

    由于没有关于给出-fno-exceptions 时的行为的文档,我假设应用程序崩溃。

    【讨论】:

    • 问题好像是问LLVM本身的编码风格,而不是同一个开发者提供的标准库的实现。
    • LLVM 可以使用自己的 c++ 编译器和自己的 STL 实现来构建。因此,要么他们应该进行预检查,这对于防止 std::bad_alloc 很难/不可能,要么崩溃。
    猜你喜欢
    • 1970-01-01
    • 2015-05-13
    • 1970-01-01
    • 1970-01-01
    • 2012-05-28
    • 2013-08-05
    • 2018-12-19
    相关资源
    最近更新 更多