15

Many embedded engineers use c++, but some argue it's bad because it's "object oriented"?

Is it true that being object oriented makes it bad for embedded systems, and if so, why is that really the case?

Edit: Here's a quick reference for those who asked:

so we prefer people not to use divide ..., malloc ..., or other object oriented practice that carry large penalty.

I guess the question is are objects considered heavyweight in the context of an embedded system? Some of the answers here suggest they are and some suggest they're not.

apaderno
  • 28,547
  • 16
  • 75
  • 90
cooper
  • 1,554
  • 1
  • 14
  • 26
  • 1
    Never seen this. Can you give an example? – egrunin Jul 18 '10 at 05:39
  • 2
    You might want to mark this question community wiki since it's more of an opinion poll than a question with a real answer. – Carl Norum Jul 18 '10 at 05:40
  • 5
    Since when does malloc have anything to do with OOP? – alternative Jul 18 '10 at 14:32
  • 2
    I didn't realise that divide and malloc were object orientated practices that carried large penalties! – Skizz Jul 19 '10 at 19:18
  • 1
    possible duplicate of [C++ usage in embedded systems](http://stackoverflow.com/questions/120957/c-usage-in-embedded-systems) – Jason S Jul 19 '10 at 19:18
  • (see also http://stackoverflow.com/questions/880603/using-c-in-an-embedded-environment, http://stackoverflow.com/questions/812717/is-there-any-reason-to-use-c-instead-of-c-for-embedded-development, etc.) – Jason S Jul 19 '10 at 19:19
  • The author added the work “other” by mistake (they probably thought it sounded better). – ctrl-alt-delor May 21 '19 at 10:43
  • Don't avoid C++ because it is Object oriented, avoid it because it is C++. It is a massive language. It is hard to learn; hard to hire for; and hard to use, even when you become an expert. There are OO languages that are as fast as C, but easier to program with. – ctrl-alt-delor May 21 '19 at 10:44

11 Answers11

14

Whilst I'm not sure it answers your question, I can summarise the reasons my previous companies source code was pure C.

It's firstly worth summarising the situation:

  • we wanted to write a large amount of "core" code that would be highly portable across a large number of ARM embedded systems (mostly mid-range mobile phones; both smart phones and ones running RTOSs of various ages)
  • the platforms generally had a workable C compiler, though some for example didn't support floating point "double"s.
  • in some cases the platform had a reasonable implementation of the standard library, but in many cases it didn't.
  • a C++ compiler was not available on most platforms, and where it was available support for the C++ standard library, STL or exceptions was highly variable.
  • debuggers often weren't available (a serial port you could send debug printfs to was considered a luxury)
  • we always had access to a reasonable amount of memory, but often not to a reasonable malloc() implementation

Given that, we worked entirely in C, and even then only a restricted set of C 89. The resulting code was highly portable. We often used object orientated concepts though.

These days "embedded" is a very wide definition. It covers everything from 8 bit microprocessors with no RAM or C compilers upto what are essentially high end PCs (albeit not running Microsoft Windows) - I don't know where your project/company sits in that range.

JosephH
  • 37,173
  • 19
  • 130
  • 154
13

Taking your quote at face value, dynamic memory allocation is completely separate concept from object-oriented software design, so it's outright false. You can have object-oriented design, and not use dynamic memory allocation.

In fact, you can do OO in C to an extent (that's what Linux kernel does). The real reason that many embedded developers don't like C++ is that it's very complex and it is hard to write straight-forward and predictable code in it. Linus has a good recent rant on why he does not like C++ (it's better and more reasoned than his old one, I promise). Probably most folks just don't articulate it very well.

Alex B
  • 82,554
  • 44
  • 203
  • 280
  • 4
    IMO its not to hard to write straight-forward/predictable code in C++. The real problem is, that it is very easy to write unpredictable code in C++, while it is quite hard in C (well if you abuse the Preprocessor its quite easy in C aswell...) – smerlin Jul 18 '10 at 12:22
  • 1
    That's not really a good rant. He just gives examples of bad code. I mean, anyone would use sctp::connect() rather than using sctp; connect(); and even if they did, you can quickly find all the usings in a file. After all, if there's not only one connect(), then it won't compile. – Puppy Jul 18 '10 at 13:26
  • 3
    @smerlin: Well stated. Poor programmers will produce poor results in any language. – Amardeep AC9MF Jul 18 '10 at 13:28
  • 1
    I'll always give him kudos for bringing Linux to the world. But I'd never hire the guy. Reading his rants he seems like a best practice misanthrope. – Amardeep AC9MF Jul 18 '10 at 13:33
  • @DeadMG: Aside from `using` declarations, C++ programmers (myself included) can and do just write `connect`: (1) in the `sctp` module; (2) when `connect` is a member of the current class or a base class; (3) (more rarely) when `connect` will be found by ADL. C++ has more complex name lookup than C. It's not "bad C++", or unusual, to use that, but there are many cases where more than one `connect` exists, and the code compiles. Maybe Linus's needs are specialised, this reason for avoiding C++ is specific to him, but I think the point is fair. It would apply to any language with virtual calls. – Steve Jessop Jul 18 '10 at 14:08
  • 1
    ... and for that matter it applies to C code which emulates virtual calls with arrays of function pointers, in parts of the Linux kernel. As soon as you're calling a function by address, you can no longer grep for the call destination as Linus requires. Still doesn't mean it's bad code, just that sometimes his preference must be sacrificed for functionality. – Steve Jessop Jul 18 '10 at 14:09
  • 2
    I very much like a couple of linus' posts in that thread. It is indeed true, in my opinion, that c++'s pass-by-reference, for example, is often very inappriate, and really not "safer" than pointers. The latter of which are really much more clearer to the caller. And i also agree with him about the specs being way clearer and for C, and about some C++ "specialists" that propose doing any and all things using templates so it's more "generic" - don't like that either. – Johannes Schaub - litb Jul 18 '10 at 19:08
  • 1
    @Amardeep: Nearly all open-source activists are arrogant misanthropes. Look for Ulrich Drepper, GregKH, Theodore Ts'o etc., you'll always find the same pattern: No company would ever hire them except for the OSS companies. Shuttleworth and de Icaza seem to be two of the very few OSS people with basic social competence. – Philipp Jul 18 '10 at 20:30
7

What makes you say that C++ is Object Oriented? C++ is multiparadigm, and not all of the features that C++ provides are useful for the embedded market due to their overheads. (So... Just don't use those features! Problem solved!)

Arafangion
  • 11,517
  • 1
  • 40
  • 72
  • 1
    @Afafangion: not really. How do you ensure that you stick to only some subset of C++ features ? The only way I see is not use any C++ libs at all... and it looks like a **Huge** limitation. – kriss Jul 19 '10 at 20:58
  • But you can still use C libraries, and some C++ libraries however you'll need to evaluate them on a case-by-case basis anyway given size and performance overheads. Also, you gain strong type checking, classes, and in some cases, better optimization. – Arafangion Jul 19 '10 at 23:07
5

Object Oriented is great for embedded systems. It focuses a lot on encapsulation, data hiding, and code sharing. One can have Object Oriented embedded systems without division or dynamic memory allocation.

Division and dynamic memory allocation are enemies of embedded systems regardless of Object Oriented, Data Oriented or procedural programming. These concepts may or may not be used in the implementation of Object Oriented designs.

Object Oriented allows for a UART class to transmit instances of Message objects without knowing the content of the Message objects. A Message could be the base class and have several descendant classes.

The C++ language helps promote safe coding in embedded systems by allowing constructors, copy constructors, and destructors, which would only remembered in the highest disciplined C language embedded systems.

Exception handling is also a pain to get working in the C language. The C++ provides better facilities embedded into the language.

The C++ language provides templates for writing common code to handle different data types. A classic example is a ring buffer or circular queue. In the C language, one would have to use "pointers to void" so that any object could be passed. C++ offers a template so one can write a Circular_Queue class that works with different data types and has better compile-time type checking.

Inheritance allows for better code sharing. The shared code is factored into a base class and child classes can be created that share the same functionality; through inheritance.

The C language profides function pointers. The C++ languages provides facilities for function objects (function pointers with attributes).

Sorry, I just don't like those people who limit embedded systems to C language because of rumors and little knowledge and experience with C++.

Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154
4

Object-oriented design by itself isn't bad. The answer lies in your quote. Especially in real-time embedded systems, you want to make your code as light and efficient as possible. The things mentioned in your quote (objects, division, dynamic memory allocation) are relatively heavyweight and can usually be replaced with simpler alternatives (for eg. using bit-manipulation to approximate division, allocating memory on the stack or with static pools) to improve performance in time-critical systems.

casablanca
  • 69,683
  • 7
  • 133
  • 150
  • 5
    Objects don't cost anything at all. Dynamic polymorphism does. – xtofl Jul 18 '10 at 06:04
  • Agreed. If you keep it simple, there should be no problem. – casablanca Jul 18 '10 at 06:09
  • Another point to make is that although objects can be created on the heap at compile time, just like "compilation-unit scope" variables in C, I have found OO-design pushes you more towards creating them dynamically, which then introduces the overhead of `malloc()/new`. Not that this is a crucial factor, I am pro OO/C++ for most embedded systems myself, and have used intensive coalescing dynamic memory management on 32-bit Cortex-M3 microcontrollers with no issues, but I thought this was worth noting. – gbmhunter Feb 22 '16 at 04:43
3

Nothing about 'object-oriented' is bad for embedded systems. OO is just a way of thinking about software.

What's bad for embedded systems is that, in general, they have less sophisticated debuggers, and C++ does a lot of crazy stuff 'behind your back', so to speak. Those pieces of hard-to-get-access-to code will drive you nuts.

Carl Norum
  • 219,201
  • 40
  • 422
  • 469
3

C++ was designed with the philosophy of don't pay for what you don't use. So apart from the lack of good embedded compilers, there's no real reason.

Maybe CFront could have compiled C++ into C, which has a myriad of compilers...

Edit: The Comeau compiler transforms C++ into plain C, so the no-compiler argument doesn't hold.

xtofl
  • 40,723
  • 12
  • 105
  • 192
  • CFront was abandoned after a failed attempt to add exception handling. – dan04 Jul 18 '10 at 06:39
  • @dan04: thanks. Another reason CFront would be helpful (exceptions in embedded code?...) – xtofl Jul 18 '10 at 20:02
  • 2
    It a little more complicated than that unfortunately. It's unlikely you'd want to try and debug/read the C code generated by a C++ to C converter, and any debugger wouldn't display or parse it well, nor is it likely to integrate well into an IDE. It may not generate C code the compiler for the platform can cope with - for many embedded platforms, the C compiler is severely limited, and does not accept full ANSI C 89 - see the Microchip PIC16 compiler for an example, which is really quite limited in what you can write. – JosephH Jul 18 '10 at 20:22
  • @JosephH: thanks. So it's about tooling, really. – xtofl Jul 19 '10 at 07:51
  • 1
    the **don't pay for what you don't use** philosophy is true to some extend, but also have counter exemples. The way STL mimick pointers with iterators is one such, price is high and iterator interface suck. To see why you can read the (allready) classical article by Andrei Alexandrescu http://www.boostcon.com/site-media/var/sphene/sphwiki/attachment/2009/05/08/iterators-must-go.pdf – kriss Jul 19 '10 at 21:14
2

As said above, it's what object-oriented / malloc / math do behind your back that carries a penalty - both in code size and CPU cycles which are usually in short supply in embedded.

As an example, including the sqrt() function in a loop added so much overhead in recursive calculations that we had to remove it and work a fast approximation around it, using a lookup table if I remember correctly.

By all means use any tools/langauges you like, but you need to at least be able to lift the lid and check just how much extra code is being generated behind your back.

John U
  • 2,886
  • 3
  • 27
  • 39
2

As others have noted, 'embedded' encompasses a broad and varied range of hardware/software options. But...

The quote you give will give microcontroller embedded types shivers. Dynamic allocation is a no-no, if you have an error, you crash the system in unpredictable ways. Divides are heavily discouraged since they take forever in execution time. Objects are only discouraged insofar as they tend to carry lot's of 'stuff' around with them, all that 'stuff' takes up space, and microcontrollers don't have any.

I think of embedded as being projects that are small and specific, you don't worry much about extensibility or portability. You write clean code in C that does only and exactly what you want your device to do, reliably. You choose one chip family so you can move your (almost the) same code among different hardware options with minor tweaks to the port your writing too or initialization of configuration fuses.

So, you don't need to define

  1. 4 wheeled Transportation
  2. Car
  3. Toyota

Since you're only working on Toyotas. And the difference in accelerations between a Camry and Corolla are stored as constants in a register.

ArielP
  • 343
  • 1
  • 5
1

Programming is always about using the right tool for the job. There are no pat answers, and that is especially true in the embedded world. If you want to become skilled in embedded development you will be just as intimately familier with C as you are with C++.

Tergiver
  • 14,171
  • 3
  • 41
  • 68
0

First, let's pick this apart:

so we prefer people not to use divide ..., malloc ..., or other object oriented practice that carry large penalty.

Division and malloc are not unique to object oriented programming, they are present in procedural languages too (and presumably functional, and whatever other paradigms you might think of).

Division and malloc can be a problem on an embedded system if the system has sufficiently limited resources, that much is true, but they will be a problem no matter what programming paradigm you use.


Onto the main issue "Is object orientation bad for embedded systems?".

Firstly, 'object orientation' is quite a broad spectrum. Some people have conflicting ideas about what it actually means. There's a minimalist definition where an object is essentially just a bundle of functions (or 'methods') and data, and there's a more 'purist' definition that also includes features like inheritance and polymorphism.

If you take the minimalist definition of OOP then no - OOP is not bad for embedded systems. It does depend on the language, but it's entirely possible for using objects to be just as cheap as not using objects (and possibly cheaper in some situations). In C++, an object (without virtual methods, which I'll get to in a moment) takes up no more memory than its individual fields would if they weren't part of an object. In C++, (the size of) an object is equal to the sum of (the size of) its parts.

However, if you take the 'puritan' view of OOP and insist on including inheritance and polymorphism then the answer is 'yes, it is bad'. Inheritance is perhaps less of a concern (depending on the language), but polymorphism via virtual methods is a definite memory chewer. virtual functions are usually implemented by maintaining a 'vtable' (a virtual method table) that stores pointers to the correct functions, and each object must store a pointer to its vtable to enable dynamic dispatch (the process of calling virtual functions) to work properly. There are circumstances in which inheritance can use more memory than solutions that don't require inheritance - typically when comparing inheritance to composition, composition sometimes uses less memory.

One last point, particularly for the case of C++ (since that's usually what people mean when they talk about using OOP on embedded systems). People often say that "C++ does strange things behind your back" - it does do some things without those things being immediately obvious when looking at the code, such as producing the vtables I mentioned earlier, however it doesn't do these things "behind your back" in an attempt to thwart you, it does these things because they are simply needed to implement the features being used. Overall there are very few detrimental things that happen 'behind the scenes', and the things it does aren't exactly arcane or mysterious, they're generally quite well known and they're things the programmer ought to be aware of when programming for an embedded system. If you don't know about them then you don't know your tools properly and you should research them some more.

Having said all that, remember that people are free to be selective with which language features they do and don't use. It makes absolute sense to avoid the more expensive features like virtual functions, but it doesn't make sense to forgo an entire language (like C++) simply because it has a few expensive entirely optional features (like virtual functions) - that's just throwing the baby out with the bathwater.

Pharap
  • 3,826
  • 5
  • 37
  • 51