Advertisement

Dominic Herity

image

Biography has not been added

Dominic Herity

's contributions
Articles
Comments
    • I said that "C++ is _almost_ exactly a superset of C". I don't know any important feature in C that C++ lacks, but there is a lot in C++ that C lacks. It seems to me that designated initializers make it a bit easier to do something you shouldn't be doing, but maybe I'm missing something. I'd welcome an article on the features in C that C++ lacks and why they're important.

    • I had a similar experience with iostreams. I resolved it by writing a lightweight substitute that only does the basics - no locales, formatting, etc. The good news was that the rest of the standard C++ library didn't cause excessive bloat.

    • All true. My motivation for the original 1998 article was to challenge the often stated proposition that C++ is _inherently_ unsuitable for embedded systems. It was aimed at C programmers who were thinking about trying it, but deterred by inaccurate assertions. I wanted to shed some light on how it works and suggested that it be adopted piecemeal to maintain productivity and minimize risk while getting comfortable with the language. I hope it convinced some people to try it and that they found the experience rewarding.

    • I don't just assume that C++ can be used as a better C. I assert it. Take your example of malloc versus new. I don't agree that malloc if preferable, but there's nothing to stop you using it in C++, if that's what you really want. Anything you can do in C, you can do in C++. No problem. My own experience is that OOD makes code clearer when it reaches somewhere between 100 and 1000 lines, so I would contend that OOD can improve clarity even in systems with a few KB of code. Of course, C++ offers more than just OOD - exceptions, templates, etc. Templates can benefit very small systems by doing compile time calculations that can't be done in C. Of course, small systems have to be handled with skill and are unforgiving of poor design choices. Think of C++ as a bigger toolbox than C. Some of the extra tools should be used with care, but don't blame the toolbox if you misuse a tool. The purpose of the article was to help C programmers understand how some of the extra tools work, so that they can make an informed decisions about when to use them. I'm all for better embedded design and refusing to use a more powerful, more expressive, language because it can be misused is a mistake. All languages can be misused and more powerful ones can be misused more.

    • Singletons have many problems. See http://stackoverflow.com/questions/137975/what-is-so-bad-about-singletons. For cases like you describe, I tend to use a function that returns a reference to an object that is statically allocated inside the function. Such an object is constructed the first time the function is called, which gives you lazy initialization, one of the good things about the singleton. So you can do something like this: class uart; uart& console() { static uart the_console(...); return the_console; } Its a little more complicated if multiple threads can make the first call. If you have multiple objects of the same class, the function could take a numeric parameter and return a reference to the correct one. This case is more complex because the objects will generally need different constructor parameters, so a statically allocated array won't do it. Something like: class timer; timer& system_timer(unsigned n) { static std::vector<timer> the_timers; if (the_timers.empty()) { // Set them up } return the_timers[n]; } You could also use a template like this. template <unsigned n> system_timer() { static timer the_timer(...); // constructor oparameters depend on n. return the_timer; } You'd need to make sure the template is only instantiated once for each n. This has the benefit that you get a compile time error if you try to access a non-existent device.

    • I took this example and fixed the errors caused by mangling of angle brackets. I got the following compile errors (with angle brackets removed) from g++ 2.5.3. They explain the issues. listing23a.cpp:30:40: error: a brace-enclosed initializer is not allowed here before '{' token listing23a.cpp:41:9: error: ISO C++ forbids initialization of member 'table' listing23a.cpp:41:9: error: making 'table' static listing23a.cpp:41:9: error: invalid in-class initialization of static data member of non-integral type 'Dict::anonymous struct [2][3]' listing23a.cpp: In member function 'const char* Dict::fromEnglish(const char*) const': listing23a.cpp:12:29: error: 'table' was not declared in this scope

    • The continued dominance of C in even 32 bit embedded systems is confirmed by my recent experience with toolchain vendors who were surprised to be asked detailed questions about C++ support. Thanks for the references to those articles. They make better use of type safety in C than my effort. I hope readers' understanding isn't impaired by my use of void*s.

    • Much of what you say is true. Debugger support for STL containers and template instantiations is taking a long time to get as good as it can be. It would certainly be difficult to re-write a C application in C++ with OOD in one go. I wouldn't generally advocate it, except as an educational exercise. Also, code won't be maintainable if the maintainers don't understand the language or the way you use it. Check out the article on migrating from C to C++ at http://www.embedded.com/electronics-blogs/cole-bin/4438613/Rethinking-C--for-embedded-systems-design.