C++ in Embedded Systems: Myth and Reality
Total Page:16
File Type:pdf, Size:1020Kb
C++ C++ in embedded systems: Myth and reality By Dominic Herity superior to C for embedded sys- Listing 1 Listing 2 Senior Software Engineer tems programming. Function name Silicon and Software Systems It aims to provide detailed Function name overloading. overloading in C. understanding of what C++ I was surprised a while ago by code does at the machine level, // C++ function name /* C substitute for */ overload example /* function name over- what I heard in a coffee break so that readers can evaluate for void foo(int i) load */ conversation during a C++ themselves the speed and size { void foo_int(int i) course. The attendees were spec- of C++ code as naturally as they //... { ulating on the relevance of C++ do for C code. } /*... */ void foo(char* s) } to embedded systems, and the To examine the nuts and { void foo_charstar(char* misconceptions that surfaced bolts of C++ code generation, //... s) drove me ultimately to write this I will discuss the major features } { article. of the language and how they void main() /*... */ { } Some perceive that C++ has are implemented in practice. foo(1); void main() overheads and costs that render Implementations will be illus- foo(“Hello world”); { it somehow unsuited to embed- trated by showing pieces of C++ } foo_int(1); ded systems programming, that code followed by the equivalent foo_charstar(“Hello world”); it lacks the control and brevity of (or near equivalent) C code. a C compiler and the machine } C, or that, while it may be suited I will then discuss some pitfalls code generated will be exactly to some niche applications, it specific to embedded systems what you would expect from a C Listing 3 will never displace C as the lan- and how to avoid them. I won’t compiler. A trivial class with guage of choice for embedded discuss the uses and subtleties This simple point invalidates member function. systems. of C++ or object-oriented (OO) any claims that a system can be / A trivial class These perceptions are wrong. design, as these topics have implemented in C, but not in class foo Where compilers and other tools been well covered elsewhere. C++. In practice, existing C code { are adequate, C++ is always can typically be re-compiled private: preferable to C as an implemen- The Myths as C++ with about the same int x; public: tation language for embedded Some of the perceptions that dis- amount of difficulty that adopt- void bar(); systems. While doing everything courage the use of C++ in embed- ing a new C compiler entails. }; that C does, it offers greater op- ded systems are: This also means that migrat- void foo::bar() portunities for expression, en- • C++ is slow ing to C++ can be done gradu- { x = 0; capsulation, re-use, and it even • C++ produces large binaries ally, starting with C and working } allows size and speed improve- • Abstraction leads to in new language features at your ments that are impractical in C. inefficiency own pace. Although this isn’t the Listing 4 Why, then, do these percep- • Objects are large best way to reap the benefits of tions persist? The main reason • Virtual functions are slow OO design, it minimises short C substitute for trivial class with member function. is that when people form their • C++ isn't ROMable term risk and it provides a basis opinions, they know a lot more • Class libraries make large for iterative changes to a work- /* C substitute for trivial class foo */ about C than about C++. They binaries ing system. struct foo have read some books, written { some code, and are competent Some of these perceptions are Front end features: a free int x; at using the features of C++, exaggerated concerns. Others are lunch }; void bar_foo(struct foo* but they lack the knowledge of just wrong. When the details of Many features of C++ are strictly this) what is happening under the C++ code generation are exam- front end issues and have no ef- { hood, the familiarity that allows ined in detail, it will be clear what fect on code generation. The ben- this->x = 0; one to visualise the disassembly the reality behind these myths is. efits conferred by these features } while typing source or even are therefore free of cost at run while formulating a design. It is Anything C can do, C++ can time. These features include use between const and non-const to these people that this article do better of the keywords const, private, data. These specifiers allow the is addressed. The most obvious property of protected, and public, which al- programmer to prevent misuse This article aims to replace ex- C++ is so obvious that it’s often low the programmer to prevent of data or interfaces through aggerated claims and misapplied overlooked: C++ is a superset of misuse of interfaces. No physical compiler-enforced restrictions. generalisations with informed C. If you write a code fragment difference exists between private, Default arguments to func- comment. It supports the view (or an entire source file) in the C protected, and public members. tions are another neat, free front that C++, used appropriately, is subset, the compiler will act like Neither is there a difference end feature. The compiler inserts 1 eetindia.com | February 1998 | EE Times-India default arguments to a function generates a reference to a label Function names are altered to Behind the protection and call, where none are specified by such as ?foo@@YAHH@Z, while add argument types, so that the scoping, a class is almost the the source. a call to a function void foo(int) two functions have different same as a C struct. Indeed, in A less obvious front end fea- generates a label like ?foo@@ names. C++, a struct is defined to be a ture is function name overload- YAXH@Z and a call to a function In C++, name mangling is au- class whose members are public ing. Function name overloading void foo(bar*) generates a label tomatic, but in a C substitute, it by default. A member function is is made possible by a remarkably like ?foo@@YAXPAU bar@@@ would be the responsibility of the a function that takes a pointer to simple compile-time mecha- Z. Name mangling ensures that programmer. an object of its class as an implicit nism. The mechanism is com- functions aren’t called with the parameter. So a C++ class with a monly called name mangling, wrong argument types and it Classes, Member Functions, member function is equivalent, but has been called name deco- also allows the same name to and Objects in terms of code generation, to a ration by those who have noth- be used for different functions Classes and member functions are C struct and a function that takes ing better to do than sanitise provided their argument types the most important new concept that struct as an argument. perfectly good terms. Anyone are different. in C++. Unfortunately, they are Listing 3 shows a trivial class who has seen a linker protesting Listing 1 shows a C++ code usually introduced without ex- foo with one member variable x the absence of ?foo@@YAHH@ fragment with function name planation of how they are imple- and one member function bar(). Z knows which term is more overloading. There are two func- mented, which tends to disorient Listing 4 shows the C substi- appropriate. Name mangling tions called foo, one taking an int C programmers from the start. In tute for Listing 3. Struct foo has modifies the label generated for argument, the other taking a char* the subsequent struggle to come the same member variable as a function using the types of the argument. to terms with OO design, hope of class foo and the member func- function arguments, or function Listing 2 shows how this understanding code generation tion foo::bar() is replaced with signature. So a call to int foo(int) would be implemented in C. quickly recedes. a function bar_foo(struct foo*). Listing 5 Listing 6 A simple string class featuring constructors, C substitute for simple string class. destructors, operator overloading, new, and delete. /* C substitute // A simplified string class for simplified string class */ #include #include #include #include using namespace std; #include class String { struct String { private: char* data; char* data; unsigned len; unsigned len; }; public: #define length_String(s) ((s)->len) String(); void StringConstructor(String* this) { ~String(); this->len = 0; unsigned length() const; this->data = 0; String& operator=(const char* s); } }; void StringDestructor(String* this) { inline unsigned String::length() const if (this->data != 0) { free(this->data); return len; } }; String operatorEquals_String_const_char_star( String::String() { String* this, const char* s) { len = 0; this->len = strlen(s); data = 0; this->data = (char*) malloc( } (this->len+1) * sizeof(char)); String::~String() { /* if (data != 0) If char had a constructor, */ delete [] data; /* it would be have to be */ } /* called here. */ String& String::operator=(const char* s) { if (this->data == 0) len = strlen(s); this->len = 0; data = new char [ len+1 ]; else if (data == 0) strcpy(this->data, s); len = 0; return *this; else } strcpy(data, s); FILE* return *this; operatorShiftLeft_ostream_unsigned(FILE*, } unsigned); void main() { void main() { String s; String s; s = “Hello world”; StringConstructor(&s); cout operatorEquals_String_const_char_star( < &s, “Hello world”); < operatorShiftLeft_ostream_unsigned(stdout, s.length(); length_String(&s)); } StringDestructor(&s); } 2 eetindia.com | February 1998 | EE Times-India Note the name of the argument Listing 7 Listing 8 of bar_foo(struct foo*) has been chosen as this, which is a key- Inheritance. C substitute for inheritance. word in C++, but not in C. The // Simple example of in- /* C Substitute for inheritance */ choice is made deliberately to heritance struct A { class A { int value; highlight the point that in C++, public: }; an object pointer named this is A(); void AConstructor(struct A* this) { implicitly passed to a member int f(); this->value = 1; function.