Programming Tips: C++ and STL
Use typeof. The typeof operator in g++ can be used for some very handy macros which save a lot of typing. For example, you often have to write something like:
    for (vector::iterator it=foo.begin(); it!=foo.end(); it++) { ... }
But with typeof, you can define a foreach macro which lets you say
    foreach(it,foo) { ... }
The trick is that foreach references typeof(foo.begin()) to extract the iterator type. Similarly, you can write a let macro which declares and initializes the first argument to the type and value of the second. These are all available in libtlb. The bad news is that typeof is a gcc extension; I'm not sure if any other compilers support it.

Compile everything together. One of the most vexing problems with C++ is the time it takes to recompile a project when a header file is changed. Often, changing a header file means that most or all of the object files need to be recompiled. This encourages 3 bad behaviors:

  • Avoiding putting comments in header files. They are most useful there, but knowing that it will cause a global recompile makes me avoid touching them when possible.
  • Avoiding changing header files, especially comments. Often comments get out of date.
  • Putting several logical modules together in one pair of files, since each .cc file adds time to the compilation.
In fact, most of the time it takes to compile a typical C++ program is processing all the include files. This is especially true when templates are used extensively, because it must generate code for all template instantiations in each .o file, most of which are redundant and discarded by the linker.

I've now gotten in the habit of making my test program just #include all the .cc files, so it looks like:

t-foo.cc
#include <std....h>
#include "foo.cc"        // includes foo.h
#include "bar.cc"        // includes bar.h
...

...main(...)
{
    foo();
    ...;
}
Below are timing measurements for a project with 15 .cc files containing 3000 lines of code and including a lot of STL headers:
Separate compilationNew way
Touch 1 .cc:3.5 sec5.1 sec
Touch 2 .cc:5.5 sec5.1 sec
Touch .h:26.1 sec5.1 sec
Since I usually have changed at least one .cc file, and often a .h file, before recompiling, this probably gives faster compiles on average. Furthermore, it eliminates the penalty for touching header files, which encourages better habits.

The only drawback is that constants in .cc files become globally visible. But now that you can change the .h files without penalty, you can make these part of the class definition where they belong anyway...

Inline. I wish I could find a way to never have separate declarations and definitions of functions. You can of course write member functions inline, but only if then don't make forward references. If you have two classes which mutually depend on each other, you just have to write some of the function definitions outside of the class declaration.

I think about someday writing a C++ preprocessor which takes a class declaration with all the code inline, and splitting out a class declaration and member function definitions separately. It would take a bunch of these files and emit one big .cc file which would have all the declarations at the top and all the definitions at the bottom so it would compile. In fact you want 3 sections: forward declarations, full declarations, and finally definitions.


Copyright 2007, Trevor Blackwell. Home