我正在使用托管的mbed C++ 编译器将 C++ 库移植到我的 mbed,该编译器基本上是 ARMCC,具有您无法真正更改的配置。他们决定的配置选项之一(出于某种未知原因)是不支持异常。所以 athrow
和 acatch
会产生编译器错误。
究竟如何才能毫无例外地使用标准 C++ 库?我在我的库中使用了一些向量。我怎么知道push_back
函数是否真的成功了?是否有任何标准方法可以知道是否发生了异常,或者它是否只是做某事exit(1)
或某事?
我正在使用托管的mbed C++ 编译器将 C++ 库移植到我的 mbed,该编译器基本上是 ARMCC,具有您无法真正更改的配置。他们决定的配置选项之一(出于某种未知原因)是不支持异常。所以 athrow
和 acatch
会产生编译器错误。
究竟如何才能毫无例外地使用标准 C++ 库?我在我的库中使用了一些向量。我怎么知道push_back
函数是否真的成功了?是否有任何标准方法可以知道是否发生了异常,或者它是否只是做某事exit(1)
或某事?
究竟如何才能毫无例外地使用标准 C++ 库?我在我的库中使用了一些向量。我怎么知道 push_back 函数是否真的成功了?是否有任何标准方法可以知道是否发生异常,或者它是否只是执行 exit(1) 之类的?
一旦你在 C++ 中禁用异常处理,你就会冒险进入非常严格的领域。
一些标准库实现,如 Dinkumware 的,允许禁用异常。有一个问题是定义一个宏,_HAS_EXCEPTIONS,为 0。STLPort 有一个类似的约定,_STLP_USE_EXCEPTIONS=0。
但是,当异常被禁用时,标准库应该做什么没有标准定义。在大多数情况下,异常处理在 C++ 语言中几乎是根深蒂固的。Evendynamic_cast
和operator new/new[]
throw 默认情况下,这些不是库功能。
即使对于不抛出异常的标准库实现,也缺乏对应该发生什么的明确定义。如果一个序列push_back
在为该序列分配更多内存的过程中抛出,应该发生什么?元素是否根本没有插入?这些序列的标准接口当然不会告诉我们什么时候发生这样的错误。
此外,许多 C++ 库通常会使用像 operator new 一样抛出的函数(而不是 nothrow 版本)。因此,一旦我们禁用异常,我们确实会冒险进入许多未定义的行为领域。
我曾经不得不在一家禁止异常处理的公司工作,因为负责的高级程序员都是过早的优化者,他们更喜欢 C,并认为 C++ 糟糕且效率低下(巧合的是,他们编写了团队中一些效率最低的代码,并且非常喜欢对于链接列表作为默认容器,由于为所有内容分配/释放了大量微小节点,导致分析热点左右显示,但这是另一回事)。
对于嵌入式系统,反对异常处理的论据可能会更强一些,但如果没有它,通常很难依赖 C++。我认为如果没有异常处理,你能做的最好的事情就是接受一种残缺的 C++ 形式,除非你想投入大量时间来寻找特定于你的特定标准库供应商的变通办法和技巧这可能比它的价值更麻烦。
他们解释了为什么这里不支持它:
传统观点(以及 armcc 编译器人员的建议)是异常的开销非常高,因此不适合此类域。目前,我们因此不支持异常(很难删除支持,但很容易添加它)。
我们肯定会在某个时候真正了解空间和时间开销(mbed 并不是真正传统的,所以也许异常是完美的!),但现在您必须坚持使用更传统的异常处理方法。
在这里:
我们不支持编译器中的异常处理,也不打算添加它。但我很高兴听到您通常如何在微控制器应用程序中使用它们,或者您的经验!但就目前而言,您将不得不转向更标准的 C 解决方案。
基于此,我可以猜测异常情况最终会出现在std::terminate()
.
根据语言标准,我不认为不支持异常是 C++ 中的合法选项。因此,您应该进行实验以查看何时发生new
或push_back()
失败,或者询问编译器背后的人。