使用不支持异常的C ++编译器?

时间:2012-03-04 07:43:59

标签: c++ exception compiler-construction armcc

我正在使用托管的mbed C++ compiler将C ++库移植到我的mbed,这是基本的ARMCC,其配置无法真正改变。他们决定的配置选项之一(出于某种未知原因)是不支持异常。因此throwcatch会产生编译错误。

如何在没有例外的情况下使用标准C ++库?我在我的库中使用了一些向量。我怎么知道push_back函数是否真的成功了?有没有任何标准方法可以知道是否发生了异常,或者只是做了exit(1)或其他什么?

2 个答案:

答案 0 :(得分:3)

  

如何在没有例外的情况下使用标准C ++库?一世   在我的库中使用一些向量。我怎么知道push_back   功能实际上成功了吗?知道是否有任何标准方式   发生异常还是只是退出(1)或其他什么?

一旦在C ++中禁用异常处理,就会冒险进入非常严格的领域。

某些标准库实现(如Dinkumware)允许禁用异常。在那里定义一个宏_HAS_EXCEPTIONS为0. STLPort与_STLP_USE_EXCEPTIONS = 0有类似的约定。

但是,禁用例外时,没有标准库应该做什么的标准定义。在大多数情况下,异常处理几乎是根植于C ++语言。默认情况下,即使dynamic_castoperator new/new[]也会抛出,但这些都不是库功能。

即使对于不抛出的标准库实现,也缺乏对应该发生什么的明确定义。如果序列push_back在为该序列分配更多内存的过程中抛出,那会发生什么?该元素是否未插入?这些序列的标准接口当然无法告诉我们何时发生这样的错误。

此外,许多C ++库通常会使用像new new(而不是nothrow版本)那样抛出的函数。因此,一旦我们禁用异常,我们就会冒险进入许多未定义的行为领域。

我曾经在一家禁止异常处理的公司工作,因为负责的高级程序员是过早的优化者,他们更喜欢C并且认为C ++很糟糕且效率低下(巧合的是,他们写了一些效率最低的代码具有强烈偏好链接列表作为默认容器的团队,由于为所有事件分配/解除分配的微小节点数量,导致分析热点左右显示,但这是另一个故事。

对于嵌入式系统,反对异常处理的论据可能会更强一些,但如果没有它,一般很难依赖C ++。我认为,如果没有异常处理,你可以做的最好的事情就是接受一种残缺的C ++形式,除非你想投入大量时间来寻找特定于你的特定标准库供应商的变通方法和技巧,否则不需要投入很多标准的库部件。这可能比它的价值更麻烦。

答案 1 :(得分:2)

他们解释了为什么不支持here

  

传统智慧(以及来自armcc编译器人员的建议)   是异常的开销很高,因此不是   适合这种域名。现在,我们不是   支持异常(很难删除支持,但很容易添加   它)。

     

我们一定会真正了解空间和时间   在某些时候开销(mbed不是真正传统的,所以也许   异常是完美的!),但是现在你必须坚持更多   传统的异常处理方法。

here

  

我们不支持编译器中的异常处理,但事实并非如此   计划添加它。但我很高兴听到你经常使用的方式   它们在您的微控制器应用程序或您的经验!但   现在,您将不得不求助于更多标准的C解决方案。

根据this,我可以猜出异常情况会在std::terminate()中结束。

我不认为不支持异常是C ++中每个语言标准的合法选项。因此,您应该进行实验,看看newpush_back()失败时会发生什么,或者询问编译器背后的人员。