为什么嵌入式C ++编译器不支持异常?

时间:2016-01-04 23:10:10

标签: c++ stl embedded avr

我正在为嵌入式系统编写一个库,而且我没有找到容易找到的STL标准库。

但是我收到的最糟糕的消息是编译器没有异常支持。 Atmel参考手册显示this

为什么不支持嵌入式环境中的例外?

很简单,不可能使用很多用C ++编写的库。 C ++与异常紧密相关,就像使用new运算符一样!

2 个答案:

答案 0 :(得分:9)

显然,除了制作该编译器的人之外,没有人可以真正回答这个问题。

我最好的猜测是,异常既耗费时间又耗费时间(当代码抛出时,时间只是一个真正的问题,但是展开表总是需要空间,而且很容易与整体大小相同代码)对于已编译的代码,加上“相当难以实现”,它可能不是编译器开发人员列表中的最高项,因此尚未实现。它是否会在未来的某个时刻显然取决于Atmel或他们转包制造他们的编译器的人。

我不是Atmel C ++实现方面的专家,但是如果编译器支持throw而不是try/catch,我会非常惊讶 - 因为那将与使用的螺丝刀一样有用。巧克力,当试图将加热器固定在充满热量的桑拿浴室时。

如果使用-fno-exceptions,如果代码中有throw,则编译器应该出错。 STL可以用-fno-exceptions编译 - 就像我编译编译器代码一样。

答案 1 :(得分:6)

具有有限ROM和RAM资源的8位AtmelAVR不适合使用STL,这对两者都施加了相当大的负担。此外,C ++异常本质上是非确定性的,因此不适合许多实时应用程序。

编译器可以实现EC ++(嵌入式C ++)"标准"。 EC ++的目标有两个:

  • 通过将语言限制为所有编译器上可用的公共子集,支持在ISO标准化语言之前的嵌入式系统中使用C ++。
  • 避免不确定性(在内存和时间上)语言/库功能不适合硬实时应用程序。

EC ++缺少的内容包括:

  • 命名空间
  • 模板
  • RTTI
  • 例外

省略名称空间完全取决于EC ++的第一个目标,现在基本上已经过时了。两个目标都省略了其他目的,并且排除了STL和std :: string库的使用。

EC ++本身现在已经基本上过时了,但它定义的子集仍适用于严重资源受限的目标,而且许多编译器支持整个或部分EC ++实施。

请注意,也许不是所有AVR的编译器都会施加这些限制,但是如果您尝试广泛使用这些功能,您很可能很快就会发现,在大多数情况下,他们在目标非常有限的CPU和内存资源上不明智。

关于new运算符的使用,默认动态内存分配(与放置新或覆盖相反)本质上是非确定性的,通常最好在实际中避免时间嵌入式系统,特别是在最小堆可用的情况下。要在不假设异常处理的情况下使用new,请使用new (std::nothrow)#include <new>),它不会抛出异常但返回空指针,如malloc()。在EC ++ newnew (std::nothrow)基本上是相同的,但后者是可移植的和明确的。

在Atmel维护的GCC-AVR开源库中缺乏对C ++的支持并不意味着一般不支持嵌入式系统,或者实际上不支持AVR。 IAR的AVR编译器支持它所指的扩展嵌入式C ++(EEC ++)以及EC ++。 EEC ++确实支持包含STL的C ++库,但有一些修改 - 没有RTTI,没有例外,没有std :: namespace(尽管支持名称空间)。在大多数32位目标上支持ISO C ++而不是EC ++通常更全面。