Thought Leadership

C++ at fault

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:

class fubar
{
   ...
public:
   fubar();
   ~fubar();
   ...
};

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 probably 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.

Comments

0 thoughts about “C++ at fault
  • Hi Colin

    I did some work at MRI when I was PMM for MCC on the topic of constructors/destructors, together with the folks at ISI. We were experimenting with OOP models for representing pSOS tasks at the time.

    The reason, I seem to recall, for these two semi-implicit methods having no return type arises from how/where there are called by the runtime when an object is instanced or freed. I also recall it being especially sticky in static contexts, where constructors run even before calling main().

    Bill W.

  • Hi Colin

    A few bones to pick. “Implicit int” is illegal in C99, and even in C89, most compilers will warn about it.

    In C++, the constructor has no name and you can’t take the address of one, so though they use function syntax to declare/define them, you can’t call them directly. The destructor is a bit less special, still no taking its address, but you can call them explicitly.

    Since they aren’t regular static or member functions, I have no real problem with them not having a return type.

    Paul

  • Adding some comments.

    Take extra precaution when defining your constructor (or any other function) body inside the class definition as it could lead to code bloat due to automatic inlining.

    Use constructor initialization lists.

Leave a Reply

This article first appeared on the Siemens Digital Industries Software blog at https://blogs.sw.siemens.com/embedded-software/2010/08/30/c-at-fault/