Personal Notes on Compilers, Course Content, and C++ Style

This page last
updated on:

May 16, 2001

Contents and Related Links

C++ Compilers

What C++ compiler do I use? At home I have changed to Metrowerks CodeWarrior Pro 6 for Windows (Metrowerks has a decent Academic price for this compiler, around $120, and for Univ of Washington students it's possible that the University Bookstore might start carrying it at an even better discount). I've found CodeWarrior to have a very decent IDE (Integrated Development Environment), and the compiler and the standard C++ library conform as close to the ISO / ANSI standard as just about any available compilers. Metrowerks is at http://www.metrowerks.com/. In the summer of 1998 I had upgraded to Borland C++ Builder 3.0, Standard version, but found the IDE very limited and frustrating when trying to compile multiple source files as straight C++ console mode applications. Another possibility I'm thinking about is to install Linux on my home system and use the Kai C++ compiler, or to download the latest GCC freely available compiler, but my time is limited and I may never get around to doing this. The main criteria on my home PC is to be as close to the C++ standard as possible (primarily for use in my classes), and since the standard has been finalized for over three years, C++ compiler vendors are now coming out with fairly conformant versions.

Outside of teaching, though, my criteria for C++ compilers can be completely different. In my last two day jobs, C++ standards compliance was not a goal, and neither was portability (this was at XYPOINT Corp: http://www.xypoint.com/ and Locate Networks, Inc: http://www.locatenetworks.com/). The main reason was that the production platform at both jobs was Sun Solaris, and the Sun C++ compiler has historically placed stability and controlled upgrades at a higher priority than standards conformance (the latest Sun C++ compiler is much closer to being standard than previous versions).

Most of my students use MS Visual C++, which has good standards conformance in some areas, poor conformance in a few others. Most of the standard library is pretty close, since MS licensed it from Dinkumware, although there are a few rather dramatic bugs. Updates are available from the Dinkumware site:

http://www.dinkumware.com/

The main problem I have with MS Visual C++ is that the non-standard areas are features that are commonly used - for example in VC++ 'for' loop variable scoping is non-standard (which makes writing portable C++ very inconvenient).


Course Content

Over the last four years of teaching C++ for UW Extension I've changed and enhanced my course material quite a bit. This includes more extensive coverage of the standard library (including the STL portions) and adding design patterns. I've also learned a lot more about C++ than I expected, and I find that everyday I discover subtle aspects about it that I didn't know before. The language standard has been official for three years, and compilers are converging on the standard so that teaching the language and the standard C++ library is not as problematic as it once was. It will still be a year or two, though, before compilers become completely (or almost completely) conforming.

I've made my share of errors - a big one is putting std::auto_ptr objects inside standard containers, which can have subtle and disastrous consequences. As a side note, the finalized standard version of std::auto_ptr class has characteristics that will not let it be compiled as template parameters in standard library container classes (if the compiler is standards conforming).

Another area I'm improving is template coverage, particularly template member functions, template overloading, template specializing, and partial template specialization. Part of this comes from having access to compilers that support at least some of these features.

The major change that I've made to my course series over the last few years was to add substantial object-oriented design (OOD) material and sessions (I've devoted at least a fourth of my courses to OOD and design pattern usage). I have found that more and more students are coming in to my classes with some previous C++ background, or at least a very strong C background, and are picking up the C++ syntax and semantics relatively easy. However this is not the case in regards to OOD experience. I think this leaves many students with a decent knowledge of the C++ language, but without a very good sense of how to design to take advantage of the powerful features of C++. This has been noticed as such a common and consistent problem that there is a Fundamentals of Object Oriented Programming / Design course that is now required as the first course in the four course C++ certificate series. This will allow me to spend a little less time on teaching OOD and design patterns fundamentals and concentrate more on applying them in C++, as well as teaching generic programming concepts and programming.

I always welcome any comments and suggestions for improvement, whether it's for my own courses or for the C++ certificate in general.

My C++ Style

Here's a list of the style guidelines that I use in my C++ code (many more guidelines will be added in the future). These are brief summaries, usually without the background explanations for why I use them. The major style guidelines are issues that I consider important and that almost every proficient C++ developer would agree with. These are guidelines that I cover in class. The minor style guidelines are matters of personal preference (although a few of them do tend to lead to safer code).

Major Style Guidelines

  • For every class, either  1) implement the copy ctor, assign op, and dtor  2) disable the copy ctor and assign op by putting the declaration in the private section, or  3) put the copy ctor, assign op, and dtor declarations in the class, but comment them out, and put an // implicit comment at the end of the line.
  • Use initializer lists on every ctor, for every member data and for each base class (if derived).
  • Always assign to every member data element, and the base class member data (call the base class assignment operator) in the overloaded assignment operator function. Similar conceptual logic applies for derived copy ctors.
  • Never use a leading underscore for an identifier and most importantly never use two or more consecutive underscores anywhere in the identifier. These are reserved for compiler identifiers, although the first is rarely a problem. From Steve Clamage: "Identifiers beginning with underscores might be reserved to the C++ implementation, depending on context and spelling. In addition, it is common to find identifiers beginning with underscores in typical system header files even if they are supposed to be available to the programmer in application programs." The compiler is under no obligation to warn of conflicts.
  • Use const comprehensively and consistently.
  • Wrap classes, functions, and constant literals in namespaces.
  • Always initialize variables / objects with parentheses, rather than '=', for efficiency, safety, and consistency reasons. '=' is only used for assignment, default arguments, and pure virtual function declarations.
  • Include user-defined or local headers before any system defined headers (eliminates surprises, due to one implementation source file including needed system headers before the user-defined header, and a new implementation source file not including the needed system header).
     

Minor Style Guidelines

  • All types (in particular class names) begin with an upper case letter.
  • All objects / variables / parameter identifiers begin with a lower case letter.
  • Constant and enum literals are usually all uppercase.
  • Most identifiers that consist of multiple words are concatenated together with an upper case letter beginning each word (i.e. mixed case).
  • Use K & R style for braces.
  • Every statement block is surrounded with braces, particularly one line statement bodies on if statements.
  • Member data has 'm' prepended to each identifier, with the next letter being upper case.
  • Explicitly qualify when using identifiers from a namespace rather than using using but also rely on Koenig lookup rules to simplify when appropriate.
  • When returning objects by value (if a non-built-in type), return them by const value.

This page constructed by Cliff Green, Copyright © 2001.