![]()
|
The results are coming in. Yes, C++ does work in embedded systems. But as many developers have found, not for all applications or instances, and generally not in down-in-the-dirt real-time code that fights for submilliseconds. And yes, C++ definitely is a boon for designing and implementing large systems. That is, as long as you don't try to force fit everything into objects. C++ hasn't replaced C; instead, it has extended C. How much beyond C you go is a matter of personal and organizational choice. Some companies-depending on their applications-go so far as to use assembly language for tight coding, but put everything else in C++. Others stick with C, turning to C++ for special situations. As an overall trend, programmers are slowly expanding their C++ content. C++ is solidly entrenched in the embedded mainstream, running on 32-bit 68k/RISC targets. "C++ is a check-off item for compilers and debuggers," says Jim Challenger, president of SDS (Oak Brook, IL). "We now use C++ for our Single Step Debugger, and it's worked out quite well. But C++ is a lot more than C; we had a very steep and painful learning curve before we got it right. Like C, you have to know what you are doing or you can get into a lot of trouble." But C++ is more than just another language. "With C++," says Mark Glick, a senior software engineer with Northern Telecom (Research Triangle Park, NC), "you're free to be a language designer. When you write a class, you're responsible for the semantics of any object of that type. This is a big burden, especially if you're just trying to get a phone to work. Many who come to C++ aren't prepared for this kind of responsibility." C, in its own minimal way, is a technology miracle. With only 29 or so operators, buttressed with powerful features like pointers, C has proven to be a hard-core implementation language for code, ranging from operating software to large applications. But C lacks any structural provisions for larger applications. C has functions, programs, and macros-that's it. Moreover, C functions are freestanding, which means they can't be nested (written inside another function). In C, large applications become collections of programs and functions; order and structure are left to the programmer. In contrast, C++ incorporates the object-oriented (OO) paradigm, which can be used to simplify and order complex programs. In fact, C++ creator Bjarne Stroustrup originally called C++ "C with classes," modeling it after Simula 67's classes. C++ extends C with classes to help organize and structure programs. You can build a hierarchy of derived classes and nest classes inside other classes. As a language, C really is concerned with types, the kind of data being operated on or passed, and minimizing type conflicts. C++ went beyond C by extending the definition of type to include abstract data types (ADTs). With ADTs, data can be encapsulated with the methods or functions that operate on it. A C++ class object is an ADT-it can incorporate data and the functions that operate on that data into a class. Then you just call those functions to operate on or get/put the data. "I'm a top-down design guy," says Glick, "and we need structure to handle large programs. We need to rise up from the bit-twiddling mindset and learn to work at a higher level. At Northern Telecom, we deal with very large programs in the telephone digital switches and switching peripherals. Code sizes are growing everywhere. But things are changing; there's less and less patience out there to put up with bugs. C++ gives us the tools to do high-level design and minimize errors." C++ offers the structure and mechanisms to handle larger, more complex programs. OO technology, with classes and inheritance, provides a way to attack a problem in a natural way. You can define a class of things, then derive classes for each of the different items. Instead of creating a sea of code, with code sets for each item, you can use the generalized base class, with overloaded or virtual to handle special cases. ADTs enable programmers to "hide" data and functions in a class that's accessed with a defined function interface by other objects or code. Moreover, C++ program execution is by derived object. Objects can be dynamically instantiated; they come into existence, do their processing, and then go away when done. Data can be held in global data or in current objects. He also advises caution when using inheritance: "Especially in a real-time system, when you're close to the metal, you want to limit inheritance. Too many levels and you can't see what's really happening. Worse, it can slow you down and affect real-time performance." C++ is a complex language, and that complexity can lead to unforeseen behaviors-like hidden operations in the run-time code-that can slow execution and use excessive memory. For example, constructors and destructors can generate chains of code that can radically alter real-time performance. Similarly, exception processing and virtual functions also can add to code bloat or slowdowns. "C++ is a 'must-have' for a compiler buy today, even if you don't use it much," says Jim Houha, a senior kernel engineer at PowerTV (Cupertino, CA), who develops set-top/smart-TV boxes and network boxes. "I'm the kernel guy," Houha says, "and only about 10% to 15% of our OS is C++." Even so, he created an object applications programming interface (API), a C++ wrapper of the OS for the higher level application code. "To ensure performance," notes Houha, "we minimize the use of constructors and don't use destructors at all. We find templates useful, but have developed our own exception handling system, which is thread-specific. To minimize overhead, it also has no destructors." C++ enables you to build complex programs with multiple classes and hierarchies. Additionally, mechanisms like operator and function overloading minimize coding by using the same references to address different code based on the current parameters (a form of polymorphism). The worm in this apple? This tactic also hides code. "In C, a programmer can see what's happening, like in assembly language," says Jim Jahncke, a senior software engineer at Divicom (Milpitas, CA). "In C++, you have to make sure you understand what's happening everywhere in the code, what's really called by an operator or function. This can get critical interfacing to hardware, where it pays to keep function calls at a low level [i.e., not pass through the inheritance hierarchy] to get performance." "C++ gives us strong typechecking," says Jahncke, "that helps to minimize type mismatch problems. At a higher level, C++ gives us an OO model that works. It's neat to see when it works, when you can add functions and hardware to our programs easily. C++ has been moving theory into practice. It works." C++'s OO technology lets programmers build a program environment that is tuned for change and supports adding new devices or functions with a minimum of reprogramming. Features like function overloading, derived class inheritance, virtual functions, templates (parameterized classes), and exception processing all provide mechanisms that aren't hardwired like assembly language or much of standard C code. "We're developing what we think is the next-generation music synthesizer/keyboard," says Bryan. "C++ let us evolve the design." Divicom also took advantage of C++'s flexibility for its dish networks. "C++ lets us hide hardware and software details behind a class interface," says Jahncke. "This makes it easy to add new devices, reuse code, and handle redesigns. We've handled three massive redesigns. Of course, you have to use C++ wisely; it takes time to learn how to create an OO design. It's a tool that needs to be used carefully." On the other hand, MacGregor isn't so sure about C++: "I learned a lot using C++; the experience was good. C++ has advantages for real-time programming-you can represent devices easily. It does a good job in holding device state in an object." But he's found, at least with instruments and different chips, that there's little real inheritance and code reuse. "When all is said and done," says MacGregor, "C++ gives you a lot of power, but you have to make a lot of compromises to get it to work effectively. And I'm not sure it's worth it. It's tempting to do your own OO extensions in C and avoid the hassle." C++ no longer is the new kid on the language block-it has progeny. Sun developed Java, a subset of C++, for embedded and network applications. One interesting aspect of C and C++ is the rush of interest and product developments for Java. Unlike C and C++, Java is interpretive, executing on a byte-code interpreter. Moreover, Java comes with a separate run-time system that isn't compiled into the applications program. That run-time system provides a base of services, including networking, security, and general graphics. Because it's interpretive, Java-like Forth and Smalltalk before it-isn't platform-dependent. The same Java program executes on any target platform, which is very useful for network and some embedded applications. Java incorporates most of C++'s OO features, but drops pointers and adds memory garbage collection. Java has attracted a lot of vendor and developer attention. "Java is attractive to the bulk of application developers who are looking for cross-platform execution," says Houha. "The people who loved C++ don't seem to love it anymore, are running into code bloat, and are backing away from features, such as operator overloading. Java extends the rules, is cleaner, and involves fewer choices." |