Colin Walls has over thirty years experience in the electronics industry, largely dedicated to embedded software. A frequent presenter at conferences and seminars and author of numerous technical articles and two books on embedded software, Colin is an embedded software technologist with Mentor … More »
C++ at fault
January 14th, 2016 by Colin Walls
I like being right. Who does not? I am also interested in programming languages. Part of their appeal is that, unlike almost all spoken languages, they have a precise definition or specification to which implementers endeavor to comply. Many languages, like C and C++, have ANSI/ISO standards, which nail down many of the details. These standards tend to be imperfect and aspects of the language can remain rather insecure, as implementers have too much latitude. This is why organizations such as MISRA publish detailed usage guidelines to avoid the problem areas. C++, in particular, gives some interesting opportunities to write obscure code, which I have written about here before.
I was concerned, when I first started to learn C++, that there was a flaw in the language. Some years later, I got the whole story …
The C++ language is generally more “picky” than C. There are tighter requirements to specify data types and use them in a consistent manner. This is good, as it reduces opportunities for programmer error. When I was learning the language, I was a little confused by constructors and destructors. In C++, there is the concept of a class. This is a construct, very like a C language struct, but it can contain both code and data. Defining a class, in effect adds a new data type to the language. There is the opportunity to include two “member functions”, which are executed when an object is instantiated from the class and when it goes out of scope; the constructor and destructor respectively. Here is an outline of a class definition:
The two functions, fubar() and ~fubar() are the constructor and destructor. Here I have just shown the declaration – the actual code is defined elsewhere.
Neither of these functions has the opportunity to return a result. So, they are intrinsically void. But you will notice that I have not declared them as such. In fact, if I did, I would get an error from the compiler. This seems illogical. In C, a function without a specified return type is, by default, int. In C++, it is normally forbidden to exclude the type specification, but not here. Confusing eh?
Some years later I got the answer to this mystery. In the early 1990s, I was working for Microtec, who were later acquired by Mentor Graphics. We had just released some of the first tools for programming embedded systems in C++ and we were promoting them and the broader use of the language. We had the idea that we would run a large seminar on C++ for embedded and, as one of our engineering team was rather well connected, we arranged for Bjarne Stroustrup, the inventor of the C++ language, to come along and speak. Needless to say, this attracted a large crowd, as we had planned. That evening, we took the Great Man out for dinner. Naturally, the conversation included some discussion of C++ and, although I was nervous about making a fool of myself, I had the chance to raise this anomaly. “Yes,” he said “we screwed up there really, but it is too late to go back and change it now.”
It was very satisfying to get the answer “from the horse’s mouth”. I suspect many modern compilers allow a void declaration. Maybe even the spec has been revised. But I think that it illustrates the point that the only silly question is the one you do not ask.