C ++ STL容器无法使用,没有例外,我们可以做些什么呢?

时间:2012-03-25 04:31:48

标签: c++ stl kernel intrusive-containers

C ++的假设是“你用什么,付钱”。然而,由于例外以及它们在STL中的普遍使用,这可能会非常虚弱。

在任何人说“只是打开异常”之前,生活对于我们必须生活的编程环境并不那么慷慨。我的是内核编程,执行环境没有提供足够的C ++运行时来展开堆栈等。

当STL容器无法为其底层后备存储重新分配存储时,它们将抛出分配失败异常。当环境中没有启用异常时,程序将会相当神秘地崩溃:我已经看到实现直接中止或只是假设分配工作即使它没有。

我遇到的许多C ADT库都是通过返回错误代码或将错误作为输出参数来提前解决此问题。

处理此问题的“最佳”C ++方法是什么?

澄清

我不想使用标准库,我不能。我不是在问“我怎么做那些无法做到的事情”。我问:“给出一个干净的平板,如何构建容器库。”

2 个答案:

答案 0 :(得分:18)

这很简单:不要相信你应该使用标准库来一切

标准库旨在成为您使用功能的默认位置。但是,这并不意味着它适用于所有情况。例如,内核编程。这是一个相当小众的环境,您需要直接和明确地控制大多数C ++程序员不关心的事情。

信令失败的C ++标准机制,特别是来自容器的内部内存分配之类的东西,是抛出异常。绝大多数应用程序都不会理会这个例外;万一他们失去记忆,他们就会死。哪个对他们没问题。在这些情况下返回错误代码是最困难的(考虑重新分配std::vector<std::string>。如果其中一个内部std::string是什么获得OOM会怎么样?谁得到错误代码?你会怎么样?甚至表示构造函数失败,因为std::string的复制构造函数抛出了异常?)。只有真正需要关心的人才会关心它。

您正在受限制的环境中工作,这是一个标准库无法处理的环境。所以...不要在那种环境中使用它。

我的建议是追踪a copy of EASTL。它真的是为这种东西而设计的。我链接到的Github repo有一些错误修复等等,但它仍然大致相同。这不是一个糟糕的代码。他们的类似STL的容器提供了大部分接口,因此它们可以主要是直接替换。但它们提供特殊功能来专门控制内存分配。他们不扔(或至少,你可以关掉投掷)。

答案 1 :(得分:3)

看来问题确实是你的环境。堆栈展开并不是非常复杂。我可以看到你为什么要对它进行一些限制 - 抛出一个10 MB的对象是合法的C ++ - 但即使在内核模式下,你也应该能够支持通过非投掷std::bad_alloc - 虚拟电话。

考虑到这一点,STL设计非常理智。该接口仅需要最少的异常支持,并且可以根据环境定制实现。