This paper was delivered to Summer AUUG meetings in both Sydney and Melbourne in March 1996.

Surviving C++: Tips and Tricks

Joan McGalliard * and Paul-Michael Agapow **
GPO Box 964G Melbourne, V.3001
* jem@netspace.net.au
** agapow@latcs1.oz.au

Abstract

C++ has rapidly become a dominant language. Yet it is complex and difficult to learn and many (like the authors) have had to teach themselves. In this paper we share some ideas, tips and approaches for learning and using C++, drawn from our own experiences and several useful works. A reading list and pointers to other useful references are included.

Introduction

Whether one likes it or not, C++ is here to stay ... at least for a while. The language's widespread and almost faddish popularity is partly justified by some very attractive features. Conversely, C++ is one of the most complex and obfuscated programming languages to ever reach general use, as many who who have learnt the language will know. This paper (which could be called "C++ for Humans") is an assortment of approaches, tips and points to help make C++ easier. While there are certainly arguments against some of our suggestions, we feel they are useful for avoiding some of the worst pitfalls. However, it should be noted that this paper is not:

Why Use C++?

For many this question will not arise, as they're obliged to use C++ for project or job reasons. For the rest of us, there are some good (albeit not great) reasons as to why you should use C++:

Books and Pointers

There are a lot of very bad C++ books available, that are not only poorly written but just plain incorrect. Therefore it is recommended that you mainly use books on which you can get a recommendation. The books you might find use for can be broken down into three classes: Of course the Internet contains a wealth of C++ information, not all of it worthwhile. Web searches for C++ will reveal an (over)abundance of information. Good places to visit would include the newsgroups comp.lang.c++ and comp.lang.c++.moderated and the C++ FAQ [22,23]. To find the right tutorial for your needs, begin looking at "Learning C++" [25] or "Learn C/C++ today" [26]. C programmers may want to go straight to "C++ Annotations" [27]. To try to come around to the object oriented paradigm look at "Understanding C++" [28]. The best general place to start looking around the web at C++ is probably "C++ Virtual Library" [24].

Style

Personal programming style (methods of commenting, use of identifiers, spacing and so on) is of course a highly personal issue and many electrons have been wasted arguing about the naturally "best" way. Despite this history however, we'll dive in and suggest that there are some stylistic conventions that are useful in the case of C++. Use of commenting and a self documenting programming style in any programming environment is of course important for readability and maintainability. With C++, the emphasis on reusability makes this issue paramount. Thus all the 'rules' of good commenting and layout apply doubly to C++. Of course, any body of code should have a unifying style.

Often in C++ you'll have several functions or variables with the same name (in different classes, or overloaded functions etc.). The compiler 'mangles' these names to try to produce unique identifiers, often using a combination of source file name, class name and object name, then - if necessary - truncating the name. If using a source code debugger or other analysis tool, the actually names of variables and functions can be quite different to that expected. Fortunately this is a problem that is vanishing with improved debuggers. Name mangling can also lead to subtle errors if mangled names "collide" (a problem that is also disappearing). For safety ensure that file names are unique across different directories in the same program. Also long identifier names should be unique in the early part of their names. For example choose func1UsedInThisBlock and func2UsedInThisBlock rather than funcUsedInThisBlock1 and funcUsedInThisBlock2). Another problem along these lines in the collision of mangled names with those in third party libraries.

On the subject of identifiers, it's good practice to give names for formal arguments for functions in their declaration and to ensure these are the same as in the function definition (i.e. don't declare functions myCleverFunc( int, char*, long, int ). Compilers won't complain about the lack of this but it's clearer both for yourself and those who come after you.

There are two ways of doing comments that are supported under all C++ compilers, the standard, C 'parenthesis' style /*...*/ (slash-asterisk), and the C++ 'to the end of line' style // (double-slash). We suggest the exclusive use of double-slash comments because :

Design and Planning

The whole concept of OO design itself is deep enough to fill several shelves of books, so we'll simply list some useful references, and emphasise that the design phase is especially important with OO languages. There are several excellent books on the subject of OO design including Meyer [19] and Booch [33] and much of the new literature on patterns including Gamma [11]. (A note on the subject of patterns: although it seems fairly complex and obfuscated, at it's heart it's a very simple and practical development that will reward study.) Try to make use of other people's work. Use the standard libraries and common algorithms whenever possible.

The Compiler is Not Your Friend

The C++ compiler writers have a tough job: they're dealing with a moving target (the as yet unrealised standard), the standards committee is writing in features that haven't been implemented yet, and language complexity is blowing out severely. All in all, this leads to buggy and eccentric compilers [12] although thankfully this situation has improved significantly over recent years. (Thus compiler related problems should hopefully be minor, unless you are forced to deal with old software.)

Headers

As per other languages, header files are the black box documentation (interface) of your code, to be used by anyone calling your code. The usual caveats for such information apply as well as the following :

Default member functions (and traps)

Every time C++ creates a class, it automatically generates a default constructor, destructor, a copy constructor and an assignment operator if you don't specify it [13]. It is important to be aware of these, and to be sure that the default ones suit your purpose.

The default constructor has no parameters, and does nothing except call the constructors of the base and member classes. It is only generated if there are no other constructors. Remember if you add a constructor later, and you have been relying on the default constructor (eg you have an array of objects), you must then supply that explicitly yourself.

Another important rule is to make destructors virtual. If an instance of a base class is a derived class, BaseClass object = new DerivedClass; then the base class' destructor must be virtual, otherwise delete object; will not call the derived class' destructor. If the base destructor is virtual, then first the derived and then the base destructor will be called.

The copy constructor can be called explicitly, and is also used when you in calling a function with call-by-value parameter. The assignment operator (=) behaves in a similar fashion, and as an massively overloaded operator, is very useful. With either of these there is a trap: if your class contains a pointer to a dynamically allocated item, then both the copy and the assignment operator will copy the pointer, not the item. Thus if the copy is deleted, the original becomes corrupted. To avoid this, you may have to write your own suitable copy and assignment.

Exceptions

C++ has turned around one of the biggest faults in most Algolic languages. Previously while unexpected cases might have been only 1% (or much less) of the live data, 90% of the code might have been for such abnormal conditions. Perhaps more importantly, the important code is cluttered with largely unused error-handling code. Thus one of the most useful features in C++ is exceptions. Exceptions allow the special cases, unexpected values and errors to be handled separately from the rest of the code and more simply. C programmers who find themselves compelled to develop in C++ sometimes dig in their heels and stick to straight Kernighan and Ritchie C. We would suggest to these people that if they adopt only one part of C++ it should be exceptions. If using objects, the use of exceptions becomes almost obligatory.

Some general hints about using exceptions :

Debugging, Tuning and Optimisation

Debugging and optimisation are often synonymous (e.g. poor performance can be called a "bug") and optimisation can introduce bugs and get in the way of debugging. A major cause of hassles in this area for C++ is the use of inline functions :

Approach With Caution

The following is a list of the more complex features of C++ that may lead you into a morass of debugging, cryptic compiler warning and convoluted code. Although the most obvious approach with problems like this is just not use them, in many cases this isn't practical. The best advice therefore is that if have to use these features budget your time appropriately, enlist the help of a guru and approach with caution.

Gotchas

Every language, of course, has a share of surprises that are just waiting to slap you in the face with the non-obvious implications of the code you have written. With C++, a lot of these stem from the fact that it is not a strict superset of C, despite the temptation to assume that it is.

Miscellanea

There are some other points on assorted topics to take note of :

Acknowledgments

Thanks for help during the preparation of this paper are extended to: John Carey and Greg Bond (Burdett, Buckeridge and Young), Michael Paddon (Australian Computing and Communications Institute).

Bibliography

[1] Al Stevens (1995) "Teach Yourself ... C++" Henry Holt & Company Inc.

[2] Bjarne Stroustrup (1991) "The C++ Programming Language, 2nd Edition", Addison-Wesley.

[3] Margaret A. Ellis and Stroustrup (1990) "The Annotated C++ Reference Manual", Addison Wesley.

[4] Gregory Satir & Doug Brown (1995), "C++ the Core Language", O'Reilly & Associates.

[5] Marshall Cline & Henry Lomow (1994) "C++ the FAQs", Addison Wesley.

[6] Steve C. McConnell (1993), "Code Complete", Microsoft Press.

[7] Dan Saks and Thomas Plum (1991), "C++ Programming Guidelines", Plum Hall.

[8] Cay Horstmann (1995) "Mastering Object Oriented Design in C++", John Wiley.

[9] Bjarne Stroustrup (1994) "The Design and Evolution of C++".

[10] Scott Meyer (1992) "Effective C++", Addison-Wesley.

[11] Erich Gamma, Richard Helm, Ralph Johnston and John Vlissades (1995) "Design Patterns", Addison-Wesley, ISBN 0-201-63361-2.

[12] P.J. Plauger (1993) "Programming Languages Guessing Games", Dr Dobbs Oct, page 16.

[13] Steven Sinofsky (1992) "Designing C++ Classes", Dr Dobbs, November, p52.

[14] Tom Cargill (1992) "C++ Programming Style", Addison-Wesley.

[15] Stan Lippman (1991) "C++ Primer", Addison-Wesley.

[16] Stephen Dewhurst and Kathy Stark (1995) "Programming in C++", Prentice-Hall.

[17] James Coplien (1992) "Advanced C++ Programming Styles and Idioms", Addison-Wesley.

[18] Steve Oualine (1995) "Practical C++ Programming", O'Reilly.

[19] Bertrand Meyer (1988) "Object-Oriented Software Construction", Prentice-Hall.

[20] Ellemtel Telecommunication Systems Laboratories (1990-1992) "Programming in C++, Rules and Recommendations", <http://www.cs.huji.ac.il/course/plab/rules.txt >

[21] Joan McGalliard, (1994) "The Genderization of Unix", Open Systems Review, August, p41-44.

[22] comp.lang.c++ FAQ, <http://www.connobj.com/cpp/cppfaq.htm>

[23] comp.lang.c++ FAQ: ASCII version, <ftp://rtfm.mit.edu/pub/usenet-by-hierarchy/comp/lang/c++/>

[24] "C++ Virtual Library", <http://info.desy.de/user/projects/C++.html>

[25] "Learning C++", <http://info.desy.de/user/projects/C++/Learning.html>

[26] "Learn C/C++ Today", <http://vinny.csd.mu.edu/learn.html>

[27] "C++ Annotations", <http://www.icce.rug.nl/docs/cplusplus/cplusplus.html>

[28] "Understanding C++: An Accelerated Introduction", <http://www.iftech.com/classes/cpp/cpp0.htm>

[29] PJ Plauger (1994) "The C++ Standard Library", Prentice Hall.

[30] "C++ Draft Standard" <http://www.cygnus.com/misc/wp/index.html>

[31] Taligent (1995) "Taligent's Guide To Designing Programs: Well-Mannered Object-Oriented Design in C++", Addison-Wesley.

[32] Taed Nelson (1993) "Finding Run-time Memory Errors", Dr Dobbs, November, p34.

[33] Grady Booch, (1991) "Object-Oriented Design With Applications", Benjamin/Cummings


Document last revised 96.2.17
ÿ