1

Some features of C++ have implied run-time cost or can lead to significant code size increases. Which features should I consider avoiding when developing for a bare-metal resource constrained microcontroller? And why?

Jon L
  • 4,258
  • 1
  • 22
  • 33
M-R
  • 769
  • 1
  • 6
  • 19
  • 1
    Without far more details, this is impossible to answer. n – Peter Smith May 21 '16 at 15:52
  • You should avoid anything for which you cannot picture the general shape of the resulting machine-language implementation or be familiar with its size and failure modes. – Chris Stratton May 21 '16 at 15:58
  • 3
    Generally the big one is dynamic memory allocation – DarthRubik May 21 '16 at 16:38
  • It really depends on your specific system,and if it has constraints like reliability or strict deadlines. – Sean Houlihane May 21 '16 at 19:35
  • 6
    http://electronics.stackexchange.com/questions/3027/is-c-suitable-for-embedded-systems – Matt Young May 21 '16 at 20:09
  • define what you mean by embedded. these days embedded means almost nothing as it is just another linux platform or other operating system. so in that case you need to remove the word embedded from your question. – old_timer May 21 '16 at 22:37
  • Here's a summary table of [C++ performance penalties](http://processors.wiki.ti.com/index.php/C%2B%2B_Support_in_TI_Compilers#Some_Comments_on_Efficiency), which was compiled by Texas Instruments. IEEE paper [An empirical comparison of C, C++, Java, Perl, Python, Rexx, and Tcl (2000)](http://page.mi.fu-berlin.de/prechelt/Biblio//jccpprt_computer2000.pdf). – Nick Alexeev Aug 21 '16 at 20:06

4 Answers4

4

Look at the MISRA (Motor Industry Software Reliability Association) guidelines for safe C. They were designed specifically for coding in C and C++ for embedded application.

Wikipedia: https://en.wikipedia.org/wiki/MISRA_C

And the MISRA-C home page: http://www.misra-c.com/

Mark
  • 2,418
  • 11
  • 14
0

This is a loaded question because avoiding a language feature can lead you to compensate for it. For instance, if you avoid using C++ classes because "vtables" take up space, but then implement your own OOP using C approaches which involve static structures containing function pointers, you've brought back vtables.

Some features can have overhead even if you don't use them, like RTTI (run time type info) and exception handling. Your compiler may have a way to turn these off.

Not using the C++ standard library and especially templates (STL) is another way to save space, provided you don't supplant these with something else that is bloated, and you actually have a way to remove the library (not have it on the target).

Be careful with how you use templates. Whenever possible, design template classes so that they are very light-weight inline functions, using an implementation that isn't a template (and so isn't expanded multiple times).

A generic container or what have you can use void * type approaches and be wrapped by a thin template that provides the type safety. Most of the functions in the wrapper are inlines that perform casting that disappears in the code.

Kaz
  • 19,838
  • 1
  • 39
  • 82
-2

C++ usage in most embedded systems designs of the past was to be avoided. In particular, the parts of C++ that create classes and using inheritance, operator and method overloading and use of lots of complex pointer structures for accessing data and/or code. There are two reasons for this, one being the typically limited RAM available in embedded microcontrollers. The second issue is one of basic raw performance if the CPU is handling the advanced features of C++.

There are still plenty of embedded applications, even today, that use the cheaper variety of microcontrollers where the same is true. The trend in the recent decades to have microcontrollers with all their FLASH (ROM) and RAM on board a single chip strengthens this argument even more.

In these more modern times there are now many embedded solutions that are using quite high performance processors that are SOC type components. These often support connection of large amounts of high bandwidth DDR dynamic RAM type memory for program execution and data store. These parts also support high density serial FLASH parts for loading the program code into the DDR RAM for execution even including an operating system like an embedded Linux or RTOS. These embedded systems have performance and memory resources that rival the typical PC performance of former times. Usage of C++ features in such a system is certainly feasible. That said there is a whole separate subject of embedded system predictable performance and reliability that comes into play where the complexity of an embedded Linux and/or the overloaded data structures of a C++ implementation come into question and in many instances are to be avoided.

Michael Karas
  • 56,889
  • 3
  • 70
  • 138
  • 4
    Overloading costs *nothing* compared to giving the same functions different names. You're spreading misinformation about many other features as well. There are parts of C++ that don't play well with resource-constrained systems, but none of the ones you mentioned are among them. – Ben Voigt May 21 '16 at 22:01
  • While I'll admit that there are various parts of C++ that have no impact on resource constrained systems I can tell you from practical own experience that there is good reason to avoid some of its features for many embedded applications. System processor architecture can play a big role here too. – Michael Karas May 21 '16 at 22:11
  • @BenVoigt the mentioned "complex pointer structures for accessing data and code" are typically an efficiency and code space loss, at least in a small system, though not uniquely a C++ thing even if more easily inadvertently created there. Of course they can make certain possible future evolutions simpler, too, and their abstraction can be useful in any system that needs to deal with a degree of polymorphism such as a simple LCD menu UI. Of course there are things not mentioned, like exceptions, which typically imply a huge hit. – Chris Stratton May 21 '16 at 22:14
  • 1
    @ChrisStratton: But none of those are contained in C++, and it's just as easy to design complex pointer structures for accessing data and code in C as it is in C++. If you look at any C++ feature that does add indirection (such as a virtual function call), you find that the C++ implementation is typically the leanest of the possible ways of accomplishing it. – Ben Voigt May 21 '16 at 22:16
  • 3
    One can certainly implement object paradigms in C with structures of data and function pointers, but it's painful enough that you realize the implementation cost of doing it, and pause to contemplate if it's truly appropriate for your goals. With C++ it's just what people habitually do, and that *lack of thinking* is where the embedded systems risk comes in. – Chris Stratton May 21 '16 at 22:18
  • 1
    @Chris: If you just use the C++ features this answer rails against, you won't get any. Other C++ features may give you one layer of pointers. You never end up with "complex pointer structures" unless your code explicitly creates that complexity. The rest of your comment seems to be about good vs bad programmers, and again applies equally to any language. – Ben Voigt May 21 '16 at 22:25
  • 1
    You end up with "complex pointer structures" any time you have polymorphic objects with overriden methods. One pointer to the object, which contains pointers to the methods. This is precisely the kind of not understanding the cost of one's decisions for which C++ programmers are rightfully criticized. – Chris Stratton May 21 '16 at 22:27
  • 2
    @ChrisStratton A virtual function isn't used *in vacuo.* It typically replaces switch or if statements, and its implementation via vtables is generally a much more compact solution than either. *Not* an 'efficiency or space loss'. – user207421 May 22 '16 at 00:49
  • @EJP - that really depends on if use of objects is justified or not, a possibility already acknowledged. If you have a lot of things that are similar in some cases but not others it can indeed be justified. But if you are using it merely from habit for things that have no similarities, then the alternative is not typically a switch or case, but rather a linear flow of code that does one thing and does it well. – Chris Stratton May 22 '16 at 00:54
  • @Chris: But it isn't a cost of objects... only of polymorphism. Statically-typed objects are just as straightforward as linear C code and much lower coupling/higher maintainability. – Ben Voigt May 22 '16 at 02:19
  • @ChrisStratton: If one doesn't use multiple inheritance, a typical implementation will create one static object per type--likely in ROM--and add one pointer to the storage footprint of each type that contains virtual methods, regardless of how many virtual methods it has or how deep its inheritance hierarchy might be. – supercat May 23 '16 at 19:42
-2

I think the language committee did actually take an official stance regarding subsets once -- it was strongly against them.

Other experts feel that there is some value to defining a subset for resource-constrained environments, but the subset language calling itself "Embedded C++" is useless.

The only provision that the official language makes for embedded use is the "hosted"-vs-"freestanding" implementation rules, which allow an embedded system to not support a "main()" function and its associated processing of command-line arguments.

Nick Alexeev
  • 37,739
  • 17
  • 97
  • 230
Ben Voigt
  • 2,743
  • 1
  • 22
  • 34