5

I was writing a library to embedded systems and I bumped into no STL standard library easy found.

But the worst news I receive is no exception support by compiler. Atmel reference manual show this

Why not support exceptions on embedded environment?

It's simple make impossible to use a lot of libraries written in C++. C++ is closely linked with exceptions, like with the new operator!

Community
  • 1
  • 1
David Kennedy
  • 370
  • 2
  • 12
  • 1
    Exceptions are slow. – lost_in_the_source Jan 04 '16 at 23:10
  • So slow, that need be removed!? Why not just recommend not use? – David Kennedy Jan 04 '16 at 23:12
  • 3
    Because then operators like `new` still throw exceptions, whether you catch them or not. I'm surprised the compiler even supported c++, because c is usually used on embedded, not c++ – lost_in_the_source Jan 04 '16 at 23:13
  • Broke all code usage that have throws, try and catch is fine? – David Kennedy Jan 04 '16 at 23:14
  • So just a throw on code make it slow? Even though this is never executed? – David Kennedy Jan 04 '16 at 23:18
  • 1
    From related questions, this comment: https://stackoverflow.com/questions/765459/how-can-you-do-c-when-your-embedded-compiler-doesnt-have-operator-new-or-stl?rq=1#comment577484_765459 Does that answer your question? – Lightness Races in Orbit Jan 04 '16 at 23:19
  • 2
    Exception support is an iceberg of runtime support and a strong dependency on the platform. Bad karma in embedded dev. Pretty pointless question btw, how is this going to make you feel better?? – Hans Passant Jan 04 '16 at 23:31
  • 1
    Some STL containers and other utilities have been ported to work on Atmel chips. I forked a github repo (https://github.com/jonesinator/avr-stl) and got it working with avr-g++ fairly recently. I think it was avr-g++ 5.2 that I was using. I'm not sure every feature works as expected, but I did write some tests for the normal ways I use most of the containers and they worked as I expected. It could be a minefield, but they work for me. – Jonesinator Jan 05 '16 at 03:04
  • @stackptr who Clifford says exists the ' new (std::nothrow) ' version of 'new', so new not throw but return nullptr or 0 – David Kennedy Jan 22 '16 at 14:38
  • @Jonesinator I think, I'm using exactly your repository – David Kennedy Jan 22 '16 at 14:44

2 Answers2

11

Obviously, nobody but the people that produce that compiler can really answer that question.

My best guess is that exceptions are both space- and time-consuming (time is only a real problem when the code throws, but space is needed for the unwind tables always, and can easily be about the same size as the overall code) for the compiled code, coupled with "rather difficult to implement", it's perhaps not the highest item on the list for the compiler developers, and thus not yet implemented. Whether it WILL be at some point in the future is obviously up to Atmel or whoever they subcontract to make their compiler.

I'm not an expert on Atmel C++ implementation, but I would be VERY surprised if the compiler supports throw, but not try/catch - since that would be about as useful as a screwdriver made from chocolate, when trying to fix the heater in a sauna that is stuck on full heat.

If you use the -fno-exceptions, the compiler should error if you have any throw in the code. And the STL can be compiled with -fno-exceptions - as that's how I compile my compiler code.

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
  • Ok, after your explanation I decide remove exceptions from project and use asserts where is possible. – David Kennedy Jan 05 '16 at 00:45
  • 1
    Atmel do not produce or sub-licence compiler at all. They provide (and presumably maintain with others) an open source C library (avr-libc) for use with GCC. IAR's C++ compiler supports what it refers to as Extended Embedded C++ (EEC++) as well as EC++. EEC++ does support a C++ library with some modifications - no RTTI, no exceptions, and not in std:: namespace. – Clifford Jan 06 '16 at 14:30
7

The 8 bit AtmelAVR with its limited ROM and RAM resources is not suited to the use of the STL which imposes a considerable load on both. Moreover C++ exceptions are intrinsically non-deterministic and therefore unsuited to many real-time applications.

A compiler may implement the EC++ (Embedded C++) "standard". The aim of EC++ was two fold:

  • to support the use of C++ in embedded systems at a time before ISO standardisation of the language, by restricting the language to a common subset available on all compilers.
  • to avoid non-deterministic (in both memory and timing) language/library features unsuited to hard-real-time applications.

Things missing from EC++ include:

  • namespace
  • templates
  • RTTI
  • exceptions

The omission of namespaces is entirely down to the first aim of EC++ and now essentially obsolete. The omission of the others are justified by both aims, and preclude the use of the STL and std::string libraries.

EC++ itself is now largely obsolete, but the subset it defines is nonetheless applicable to severely resource constrained targets, and many compilers support whole or partial EC++ enforcement.

Note that perhaps not all compilers for AVR impose these restrictions, but if you attempt to use these features extensively you will probably soon discover whey they are ill advised in most cases on targets very limited CPU and memory resources.

With respect to the use of the new operator, default dynamic memory allocation (as opposed to placement new or an override), is intrinsically non-deterministic and often best avoided in real-time embedded systems, and especially so where minimal heap is available. To use new without the assumption of exception handling, use new (std::nothrow) (#include <new>) which will not throw an exception but return a null pointer like malloc(). In EC++ new and new (std::nothrow) are essentially the same thing, but the latter is portable and explicit.

Lack of support for C++ in Atmel's maintained open-source library for GCC-AVR does not mean that there is no support for embedded systems in general, or indeed for AVR. IAR's AVR compiler supports what it refers to as Extended Embedded C++ (EEC++) as well as EC++. EEC++ does support a C++ library including STL with some modifications - no RTTI, no exceptions, and not in std:: namespace (although namespaces are supported). Support for ISO C++ as opposed to EC++ on most 32 bit targets is generally more comprehensive.

Clifford
  • 88,407
  • 13
  • 85
  • 165
  • I knew noexcept function specifier but nothrow is new to me. Thank's it was enlightening. – David Kennedy Jan 08 '16 at 21:03
  • 1
    I do not see a real reason to forbid templates. I know they can be abused, but they are not inherently costly in themselves, such as exceptions. – Germán Diago Nov 19 '16 at 05:06
  • Ok, nothrow isn't a silver bullet, if I want use the default STL library to a embedded device I had to take STL code, replace all new operators by new (std::nothrow), replace try/catch by if checks and pass trough all function call the possible exception instead throw it. – David Kennedy Mar 14 '18 at 14:58
  • @DavidKennedy I didn't say it was, I also advised against using STL on such a target. Your question was about why exceptions were not supported, not how to implement STL. I know it was a while ago, but you might take a look at https://www.etlcpp.com/ – Clifford Jan 20 '23 at 18:35