C++ at fault

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.

Preparing Recommendations

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.

About Colin Walls

imageI have over twenty-five 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, I am a member of the marketing team of the Mentor Graphics Embedded Systems Division, and am based in the UK. Away from work, I have a wide range of interests including photography and trying to point my two daughters in the right direction in life. Visit The Colin Walls Blog

More Posts by Colin Walls

More Blog Posts

Preparing Recommendations

Comments (↓ Add Your Own)

5 Comments on this Post

Commented on 11:33 PM, Aug 30, 2010
By Bill Weinberg

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.

Commented on 9:16 AM, Sep 1, 2010
By Paul Floyd

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

Commented on 9:37 AM, Sep 1, 2010
By Colin Walls

Fair comments Paul. C99 certainly cleaned things up a bit. Interesting debate as to whether a constructor is really a function or just something that looks a bit like one.

Commented on 6:21 PM, Sep 9, 2010
By James Parker

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.

Commented on 9:18 AM, Sep 16, 2010
By David Brown

It's not C++ that "screwed up" by making the default void, it was the original C that "screwed up" by having an implicit int.

Add Your Comment

Please complete the following information to comment or sign in.

(Your email will not be published)