Blog posts tagged: g++

News and other things I find interesting


RSS Feed


Jul
28
2009

Slow compilation time in C/C++

Last modified: Friday, April 22, 2011

Compilation in C/C++ is a very big operation due to C/C++'s complex grammar. Source files typically residing in .cpp are always only compiled one time; however, header files typically residing in .h files are compiled once per compiler execution. Each header file needs to be recompiled because there could be different effects made from the preprocessor.

Since an individual header file is often compiled many times, header compilation as a whole can make up a large part of your total C/C++ compilation time.

Two of ways you can do to reduce this portion of compilation time is:

  1. Forward declarations
  2. Precompiled headers

Forward declarations

Extensively using forward declarations at all times will give you the biggest performance in compilation time.

Forward declaration means to declare something without defining it in a header file. Include the header file instead in the source file where it will be compiled and parsed only once.

c.h:

class C
{
public:
  C()
  {
  }
};

d.h:

class C; //<--- This is a forward declaration

class D
{
public:
  D()
  {
  }

  C c;
};

Notice that d.h does not include c.h even know it uses a class declared in c.h

main.cpp:

#include "c.h"
#include "d.h"

int main(int argc, char **argv)
{
  D d;
  return 0;
}

In main.cpp it is important that you include c.h before d.h; otherwise, the compiler will complain about C being an undefined type.

Note you can also perform forward declarations with template types:

template <typename T>
class CMyClass;

Precompiled headers

Precompiled headers allow you to speed up compile time when compiling C++ source code. You typically put anything in a precompiled header that doesn't change often or ever such as the standard library includes or boost includes.

Precompiled headers are available for most C++ compilers including GCC and Visual C++. Both of those implementations are similar.

Only 1 precompiled header can be included per compilation, so therefore at a minimum per file. But in a single project you can have several different precompiled headers.

In Visual C++ the compiled headers have an extension of .pch and in GCC they have an extension of .gch.

In GCC you compile headers just like any other file but you put the output inside a file with a suffix of .gch.

So for example if you precompile stdafx.h you will have a precompiled header that will be automatically searched for called stdafx.h.gch anytime you include stdafx.h

stdafx.h:

#include <string>
#include <stdio.h>

a.cpp:

#include "stdafx.h"

int main(int argc, char**argv)
{
  std::string s = "Hi";
  return 0;
}

Then compile as:

> g++ -c stdafx.h -o stdafx.h.gch
> g++ a.cpp
> ./a.out

Your compilation will work even if you remove stdafx.h after step 1.

Tags:

Add a new comment | 2 comment(s)

Gravatar image Jack on Wednesday, July 28, 2010 (04:07:30) says:

Brian,

Unfortunately your forward declaration example does not seem to be demonstrating anything. main.cpp will compile just fine without the forward declaration in d.h.

Perhaps there is something missing from the example? I am interested because I have a rather large C++ project that I would love to speed the compile time up for.

Jack

Gravatar image Brian R. Bondy on Monday, August 02, 2010 (09:08:47) says:

Ya the example was just to show what a forward declaration is. You can see the benefit in a large header file that has a lot of things in it. When header files include other header files you then have a lot of parsing that you don't need to do.