Why Embedded C++ compilers not support exceptions? - c++

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!

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.

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.

Related

How to find Boost libraries that does not contain any platform specific code

For our current project, we are thinking to use Boost framework.
However, the project should be truly cross-platform and might be shipped to some exotic platforms. Therefore, we would like to use only Boost packages (libraries) that does not contain any platform specific code: pure C++ and that's all.
Boost has the idea of header-only packages (libraries).
Can one assume that these packages (libraries) are free from platform specific code?
In case if not, is there a way to identify these kind of packages of Boost?
All C++ code is platform-specific to some extent. On the one side, there is this ideal concept of "pure standard C++ code", and on the other side, there is reality. Most of the Boost libraries are designed to maintain the ideal situation on the user-side, meaning that you, as the user of Boost, can write platform-agnostic standard C++ code, while all the underlying platform-specific code is hidden away in the guts of those Boost libraries (for those that need them).
But at the core of this issue is the problem of how to define platform-specific code versus standard C++ code in the real world. You can, of course, look at the standard document and say that anything outside of it is platform-specific, but that's nothing more than an academic discussion.
If we start from this scenario: assume we have a platform that only has a C++ compiler and a C++ standard library implementation, and no other OS or OS-specific API to rely on for other things that aren't covered by the standard library. Well, at that point, you still have to ask yourself:
What compiler is this? What version?
Is the standard library implementation correct? Bug-free?
Are those two entirely standard-compliant?
As far as I know, there is essentially no universal answer to this and there are no realistic guarantees. Most exotic platforms rely on exotic (or old) compilers with partial or non-compliant standard library implementations, and sometimes have self-imposed restrictions (e.g., no exceptions, no RTTI, etc.). An enormous amount of "pure standard C++ code" would never compile on these platforms.
Then, there is also the reality that most platforms today, even really small embedded systems have an operating system. The vast majority of them are POSIX compliant to some level (except for Windows, but Windows doesn't support any exotic platform anyways). So, in effect, platform-specific code that relies on POSIX functions is not really that bad since it is likely that most exotic platforms have them, for the most part.
I guess what I'm really getting at here is that this pure dividing line that you have in your mind about "pure C++" versus platform-specific code is really just an imaginary one. Every platform (compiler + std-lib + OS + ext-libs) lies somewhere along a continuum of level of support for standard language features, standard library features, OS API functions, and so on. And by that measure, all C++ code is platform-specific.
The only real question is how wide of a net it casts. For example, most Boost libraries (except for recent "flimsy" ones) generally support compilers down to a reasonable level of C++98 support, and many even try to support as far back as early 90s compilers and std-libs.
To know if a library, part of Boost or not, has wide enough support for your intended applications or platforms, you have the define the boundaries of that support. Just saying "pure C++" is not enough, it means nothing in the real world. You cannot say that you will be using C++11 compilers just after you've taken Boost.Thread as an example of a library with platform-specific code. Many C++11 implementations have very flimsy support for std::thread, but others do better, and that issue is as much of a "platform-specific" issue as using Boost.Thread will ever be.
The only real way to ever be sure about your platform support envelope is to actual set up machines (e.g., virtual machines, emulators, or real hardware) that will provide representative worst-cases. You have to select those worst-case machines based on a realistic assessment of what your clients may be using, and you have to keep that assessment up to date. You can create a regression test suite for your particular project, that uses the particular (Boost) libraries, and test that suite on all your worst-case test environments. Whatever doesn't pass the test, doesn't pass the test, it's that simple. And yes, you might find out in the future that some Boost library won't work under some new exotic platform, and if that happens you need to either get the Boost dev-team to add code to support it, or you have to re-write your code to get around it, but that's what software maintenance is all about, and it's a cost you have to anticipate, and such problems will come not only from Boost, but from the OS and from the compiler vendors too! At least, with Boost, you can fix the code yourself and contribute it to Boost, which you can't always do with OS or compiler vendors.
We had "Boost or not" discussion too. We decided not to use it.
We had some untypical hardware platforms to serve with one source code. Especially running boost on AVR was simply impossible because RTTI and exceptions, which Boost requires for a lot of things, aren't available.
There are parts of boost which use compiler specific "hacks" to e.g. get information about class structure.
We tried splitting the packages, but the inter dependency is quite high (at least 3 or 4 years ago).
In the meantime, C++11 was underway and GCC started supporting more and more. With that many reasons to use from boost faded (Which Boost features overlap with C++11?). We implemented the rest of our needs from scratch (with relative low effort thanks to variadic templates and other TMP features in C++11).
After a steep learning curve we have all we need without external libraries.
At the same time we have pondered the future of Boost. We expected the newly standardized C++11 features would be removed from boost. I don't know the current roadmap for Boost, but at the time our uncertainty made us vote against Boost.
This is not a real answer to your question, but it may help you decide whether to use Boost. (And sorry, it was to large for a comment)

C++ Standard Library Portability

I work on large scale, multi platform, real time networked applications. The projects I work on lack any real use of containers or the Standard Library in general, no smart pointers or really any "modern" C++ language features. Lots of raw dynamically allocated arrays are common place.
I would very much like to start using the Standard Library and some of the C++11 spec, however, there are many people also working on my projects that are against because "STL / C++11 isn't as portable, we take a risk using it". We do run software on a wide variety of embedded systems as well as fully fledged Ubuntu/Windows/Mac OS systems.
So, to my question; what are the actual issues of portability with concern to the Standard Library and C++11? Is it just a case of having g++ past a certain version? Are there some platforms that have no support? Are compiled libraries required and if so, are they difficult to obtain/compile? Has anyone had serious issues being burnt by non-portable pure C++?
Library support for the new C++11 Standard is pretty complete for either Visual C++ 2012, gcc >= 4.7 and Clang >= 3.1, apart from some concurrency stuff. Compiler support for all the individual language features is another matter. See this link for an up to date overview of supported C++11 features.
For an in-depth analysis of C++ in an embedded/real-time environment, Scott Meyers's presentation materials are really great. It discusses costs of virtual functions, exception handling and templates, and much more. In particular, you might want to look at his analysis of C++ features such as heap allocations, runtime type information and exceptions, which have indeterminate worst-case timing guarantees, which matter for real-time systems.
It's those kind of issues and not portability that should be your major concern (if you care about your granny's pacemaker...)
Any compiler for C++ should support some version of the standard library. The standard library is part of C++. Not supporting it means the compiler is not a C++ compiler. I would be very surprised if any of the compilers you're using at the moment don't portably support the C++03 standard library, so there's no excuse there. Of course, the compiler will have to be have been updated since 2003, but unless you're compiling for some archaic system that is only supported by an archaic compiler, you'll have no problems.
As for C++11, support is pretty good at the moment. Both GCC and MSVC have a large portion of the C++11 standard library supported already. Again, if you're using the latest versions of these compilers and they support the systems you want to compile for, then there's no reason you can't use the subset of the C++11 standard library that they support - which is almost all of it.
C++ without the standard library just isn't C++. The language and library features go hand in hand.
There are lists of supported C++11 library features for GCC's libstdc++ and MSVC 2012. I can't find anything similar for LLVM's libc++, but they do have a clang c++11 support page.
The people you are talking to are confusing several different
issues. C++11 isn't really portable today. I don't think any
compiler supports it 100% (although I could be wrong); you can
get away with using large parts of it if (and only if) you limit
yourself to the most recent compilers on two or three platforms
(Windows and Linux, and probably Apple). While these are the
most visible platforms, they represent but a small part of all
machines. (If you're working on large scale networked
applications, Solaris will probably be important, and Sun CC.
Unless Sun have greatly changed since I last worked on it, that
means that there are even parts of C++03 that you can't count
on.)
The STL is a completely different issue. It depends partially
on what you mean by the STL, but there is certainly no
portability problem today in using std::vector. locale
might be problematic on a very few compilers (it was with Sun
CC—with both the Rogue Wave and the Stlport libraries),
and some of the algorithms, but for the most part, you can
pretty much count on all of C++03.
And in the end, what are the alternatives? If you don't have
std::vector, you end up implementing something pretty much
like it. If you're really worried about the presence of
std::vector, wrap it in your own class—if ever it's not
available (highly unlikely, unless you go back with a time
machine), just reimplement it, exactly like we did in the
pre-standard days.
Use STLPort with your existing compiler, if it supports it. This is no more than a library of code, and you use other libraries without problem, right?
Every permitted implementation-defined behaviour is listed in publicly available standard draft. There is next to nothing less portable in C+11 than in C++98.

Working with a C++ compiler that doesn't support exceptions?

I'm porting a C++ library to my mbed using the hosted mbed C++ compiler which is basically ARMCC with a configuration that you can't really change. One of the configuration options they decided on (for some unknown reason) is that exceptions are not supported. So a throw and a catch will yield compiler errors.
How exactly can you use the standard C++ library without exceptions? I use some vectors in my library. How do I know if the push_back function actually succeeded? Is there any standard way of knowing if an exception occurred or does it just do an exit(1) or something?
How exactly can you use the standard C++ library without exceptions? I
use some vectors in my library. How do I know if the push_back
function actually succeeded? Is there any standard way of knowing if
an exception occurred or does it just do an exit(1) or something?
You're venturing into very restrictive territory once you disable exception handling in C++.
Some standard library implementations, like Dinkumware's, allows one to disable exceptions. There it's a matter of defining a macro, _HAS_EXCEPTIONS, as 0. STLPort has a similar convention with _STLP_USE_EXCEPTIONS=0.
However, there is no standard definition of what standard libraries should do when exceptions are disabled. Exception-handling, for the most part, is pretty much ingrained into the C++ language. Even dynamic_cast and operator new/new[] throw by default and those are not library features.
There's also a lack of a clear definition of what should happen even for the standard library implementations that don't throw. If a sequence push_back throws in the process of allocating more memory for that sequence, what should happen? Is the element simply not inserted? The standard interfaces of these sequences certainly tells us nothing about when such an error occurs.
Furthermore, a lot of C++ libraries in general will be using functions that do throw like operator new (and not the nothrow versions). As a result, we do venture into a lot of undefined behavior territory once we disable exceptions.
I once had to work in a company which forbid exception-handling since the senior programmers in charge were premature optimizers who preferred C and thought C++ was awful and inefficient (coincidentally, they wrote some of the most inefficient code on the team with a strong preference for linked lists as a default container which caused profiling hotspots to show up left and right due to the sheer number of tiny nodes being allocated/deallocated for everything, but that's another story).
With embedded systems, the argument against exception handling might be a bit stronger, but it does become difficult to rely on C++ in general without it. I think the best you can do without exception-handling is accept a crippled form of C++ without a lot of the standard library parts that throw unless you want to invest a lot of time trying to find workarounds and tricks specific to your particular standard library vendor which might be more trouble than it's worth.
They explain why it's not supported here:
The conventional wisdom (and the advice from the armcc compiler guys)
is that the overhead of exceptions is pretty high and therefore not
appropriate for this sort of domain. For now, we are therefore not
supporting exceptions (it is hard to remove support, but easy to add
it).
We'll definitely look at really understanding the space and time
overheads at some point (mbed isn't really conventional, so perhaps
exceptions are perfect!), but for now you'll have to stick to more
conventional exception handling approaches.
And here:
We don't support exception handling in the compiler, and it is not
planned to add it. But i'd be happy to hear about how you usually use
them in your microcontroller applications, or your experiences! But
for now, you will have to turn to more standard C solutions.
Based on this I can guess the exceptional situations would end up in std::terminate().
I don't think that not supporting exceptions is a legal option in C++ per the language standard. So, you should either make an experiment to see what happens when new or push_back() fails or ask the people behind the compiler.

What C++(98/03) features are not-so-well supported by poor compilers?

Often I read of some software cutting out some C++ features in order to be compliant with poor/old/exotic C++ compilers.
This one is just the last one I got into: Box2D isn't using namespaces because they need to support:
poor C++ compilers where namespace support can be spotty
A bigger example I can think of is Qt, which is relying upon MOC, is limiting template usage a lot and is avoiding templates (well, this is at least true for Qt3 and previous versions, Qt4 is mostly doing that to keep to their conventions).
I'm wondering what compilers are that poor?
There are lots of C++ compilers out there (I never heard of most of them), but I would hope that all of them are supporting most common(/simple?) C++ features like namespaces (unless they're dead); isn't this the case?
What are the most unsupported features?
I can easily expect the lack of external templates, maybe template partial specialization and similar features. At most even RTTI or exceptions, but I would have never suspected of namespaces.
In my experience, people are just scared of new things and especially things that broke on them once, 20 decades ago. There's no valid reason against using namespaces in anything written during this century.
If you're looking for things to toss out though, if you happened to be targeting windows not too long ago you had to do more than just toss features out of C++ and not use them, you had to use different syntax. Templates come to mind as one of the worse supported features in VC. They've gotten much better but still fail sometimes.
Another one that is not supported by that particular compiler (STILL!) is overloading virtual functions to return derived type pointers to the types the base version returned when using MI. VC just plain freaks out and you end up having to do virtual_xxx() and providing non-virtual "xxx()" functions to replicate the standard behavior.
What are the most unsupported features?
Let's abstract away export, which, sadly, was an experiment that failed. Then, by count of compiler users this is probably two-phase lookup, which Visual C++ still doesn't properly implement. And VC has a lot of users.
Basically anything that was added as part of the standardization process in C++98. That is:
Templates (Not just partial specialization -- I mean all templates)
Exceptions (Often because this one requires runtime support/overhead -- they're often not available on things like microcontrollers)
Namespaces
RTTI
If you go even older, you can add
Most everything in the standard library.
Several old compilers are just plain bad; OTOH I would strongly not recommend worrying about them. There are already several good and freely available reasonably standards compliant compilers available for pretty much every platform of which I am aware (mostly via G++).
Namespaces have been around forever. Some of the darker places in templates, maybe. But namespaces? No way. Even with templates, the vast, vast majority of usage scenarios are fine. Some compilers aren't perfect (they're software), but flat out not supporting a C++03 feature that isn't export? That just doesn't happen. Most compilers extend the language, not reduce it, and are moving to support C++0x.
RTTI and exceptions are often accused of poorly efficient implementations, but not poor implementation conformance.
If you are programming in the main stream with a main stream compiler then usually you find everything in the C++03 standard supported (except export as mentioned by sbi (but then again nobody used the feature (as it was not supported)). The further from the main stream the compiler is the less features usually (but they are all moving forward (some more slowly than others))
Its only when you get to less used hardware that has its own proprietary compiler that support for features start to dwindle.
The main example would be mobile devices and their associated compilers (though because of their popularity in the main stream in recent years these compilers are getting updated more quickly than before).
A secondary example would by SOC devices. There compilers are so specific that they are usually in house compilers and only get as much work on them as the SOC company can afford and as a result tend to lag a long way (or at least further) behind other compilers.
Value Initialization (C++03 feature) is not properly implemented in MSVC++.
Qt doesn't use templates much because it is older than templates.

Developing embedded software library, C or C++?

I'm in the process of developing a software library to be used for embedded systems like an ARM chip or a TI DSP (for mostly embedded systems, but it would also be nice if it could also be used in a PC environment). Obviously this is a pretty broad range of target systems, so being able to easily port to different systems is a priority.The library will be used for interfacing with a specific hardware and running some algorithms.
I am thinking C++ is the best option, over C, because it is much easier to maintain and read. I think the additional overhead is worth it for being able to work in the object oriented paradigm. If I was writing for a very specific system, I would work in C but this is not the case.
I'm assuming that these days most compilers for popular embedded systems can handle C++. Is this correct?
Is there any other factors I should consider? Is my line of thinking correct?
If portability is very important for you, especially on an embedded system, then C is certainly a better option than C++. While C++ compilers on embedded platforms are catching up, there's simply no match for the widespread use of C, for which any self-respecting platform has a compliant compiler.
Moreover, I don't think C is inferior to C++ where it comes to interfacing hardware. The amount of abstraction is sufficiently low (i.e. no deep class hierarchies) to make C just as good an option.
There is certainly good support of C++ for ARM. ARM have their own compiler and g++ can also generate EABI compliant ARM code. When it comes to the DSPs, you will have to look at their toolchain to decide what you are going to do. Be aware that the library that comes with a DSP may well not implement the full C or C++ standard library.
C++ is suitable for low-level embedded development and is used in the SymbianOS Kernel. Having said that, you should keep things as simple as possible.
Avoid exceptions which may demand more library support than what is present (therefore use new (std::nothrow) Foo instead of new Foo).
Avoid memory allocations as much as possible and do them as early as possible.
Avoid complex patterns.
Be aware that templates can bloat your code.
I have seen many complaints that C++ is "bloated" and inappropriate for embedded systems.
However, in an interview with Stroustrup and Sutter, Bjarne Stroustrup mentioned that he'd seen heavily templated C++ code going into (IIRC) the braking systems of BMWs, as well as in missile guidance systems for fighter aircraft.
What I take away from this is that experts of the language can generate sophisticated, efficient code in C++ that is most certainly suitable for embedded systems. However, a "C With Classes"[1] programmer that does not know the language inside out will generate bloated code that is inappropriate.
The question boils down to, as always: in which language can your team deliver the best product?
[1] I know that sounds somewhat derogatory, but let me say that I know an awful lot of these guys, and they churn out an awful lot of relatively simple code that gets the job done.
C++ compilers for embedded platforms are much closer to 83's C with classes than 98's C++ standard, let alone C++0x. For instance, some platform we use still compile with a special version of gcc made from gcc-2.95!
This means that your library interface will not be able to provide interfaces with containers/iterators, streams, or such advanced C++ features. You'll have to stick with simple C++ classes, that can very easily be expressed as a C interface with a pointer to a structure as first parameter.
This also means that within your library, you won't be able to use templates to their full power. If you want portability, you will still be restricted to generic containers use of templates, which is, I'm sure you'll admit, only a very tiny part of C++ templates power.
C++ has little or no overhead compared to C if used properly in an embedded environment. C++ has many advantages for information hiding, OO, etc. If your embedded processor is supported by gcc in C then chances are it will also be supported with C++.
On the PC, C++ isn't a problem at all -- high quality compilers are extremely widespread and almost every C compiler is directly associated with a C++ compiler that's quite good, though there are a few exceptions such as lcc and the newly revived pcc.
Larger embedded systems like those based on the ARM are generally quite similar to desktop systems in terms of tool chain availability. In fact, many of the same tools available for desktop machines can also generate code to run on ARM-based machines (e.g., lots of them use ports of gcc/g++). There's less variety for TI DSPs (and a greater emphasis on quality of generated code than source code features), but there are still at least a couple of respectable C++ compilers available.
If you want to work with smaller embedded systems, the situation changes in a hurry. If you want to be able to target something like a PIC or an AVR, C++ isn't really much of an option. In theory, you could get (for example) Comeau to produce a custom port that generated code you could compile on that target's C compiler -- but chances are pretty good that even if you did, it wouldn't work out very well. These systems are really just too limitated (especially on memory size) for C++ to fit them well.
Depending on what your intended use is for the library, I think I'd suggest implementing it first as C - but the design should keep in mind how it would be incorporated into a C++ design. Then implement C++ classes on top of and/or along side of the C implementation (there's no reason this step cannot be done concurrently with the first). If your C design is done with a C++ design in mind, it's likely to be as clean, readable and maintainable as the C++ design would be. This is somewhat more work, but I think you'll end up with a library that's useful in more situations.
While you'll find C++ used more and more on various embedded projects, there are still many that restrict themselves to C (and I'd guess this is more often the case than not) - regardless of whether or not the tools support C++. It would be a shame to have a nice library of routines that you could bring to a new project you're working on, but be unable to use them because C++ isn't being used on that particular project.
In general, it's much easier to use a well-designed C library from C++ than the other way around. I've taken this approach with several sets of code including parsing Intel Hex files, a simple command parser, manipulating synchronization objects, FSM frameworks, etc. I'm planning on doing a simple XML parser at some point.
Here's an entirely different C++-vs-C argument: stable ABIs. If your library exports a C ABI, it can be compiled with any compiler that works on the system, because C ABIs are generally platform standards. If your library exports a C++ ABI, it can only be compiled with a matching compiler -- because C++ ABIs are usually not platform standards, and often differ from compiler to compiler and even version to version.
Interestingly, one of the rare exceptions to this is ARM; there's an ARM C++ ABI specification, and all compliant ARM compilers follow it. This is not true on x86; on x86, you're lucky if a C++ library compiled with a 4.1 version of GCC will link correctly with an application compiled with GCC 4.4, and don't even ask about 3.4.6.
Even if you export a C ABI, you can have problems. If your library uses C++ internally, it will then link to libstdc++ for things in the C++ std:: namespace. If your user compiles a C++ application that uses your library, they'll also link to libstdc++ -- and so the overall application gets linked to libstdc++ twice, and their libstdc++ may not be compatible with your libstdc++, which can (or so I understand) lead to odd errors from the intersection of the two. Considerably less likely, but still possible.
All of these arguments only apply because you're writing a library, and they're not showstoppers. But they are things to be aware of.