// JP opened flex table

Click to See Complete Forum and Search --> : MSVC 6.0 preprocessor and include file


simonr
July 2nd, 2002, 05:15 AM
Hi,

We are currently looking at ways to speed up compilation time. We use precompiled headers already to good effect. My questions are:

1) We seem to have noticed using pragmas that the preprocessor parses files even though they are protected by previously defined include guards. As far as we can see this means it is doing a lot of unnecessary work. Is this correct and can we stop it.?

e.g. if we have a header file afile.h that is included by multiple cpp files in a library, when compiling the library the pragma message pops up for each file that include the header...

#ifndef _AFILE_H
#define _AFILE_H
#pragma message("Parsing after include guard")

This presumably means it parses sub-included files too. If we can stop it it should speed us up.

2) We are careful to avoid unnecessary includes, especially in header files, but in a big evolving project quite a few still slip though the net. Is there an automated way of detected and stripping out uneeded #includes?

Thanks,
Simon

cup
July 2nd, 2002, 06:06 AM
To speed up compilations, what I used to do was to keep everything local. Network access slows down compilations dramatically. This is one of the killers.

Your trick of not having unnecessary includes may work but it is normally more trouble than it is worth. If you use STL/ATL/WTL, you may not be able to prevent it.

One of the tricks I use is to only have pointers/references to other classes. That way, a forward declaration will suffice. There is no need to include the header file which contains the definition.

Another trick is to use the CORBA style tie-class. This just provides an interface and nothing else. eg Supposing there are lots of dependencies on a class


#ifndef Biggy_h
#define Biggy_h
#include "Medium.h"
#include "Small.h"
class Biggy
{
...
Medium* GetMedium ();
private:
void ShrinkIt ();
void GrowIt ();
Medium mMed;
Small mSmall;
};
#endif


You could get around this by implementing the private data and functions in an internal private class


// Header
#ifndef Biggy_h
#define Biggy_h
class BiggyP;
class Medium;
class Biggy
{
public:
Biggy ();
void SubOne ();
Medium* GetMedium ();
...
private:
BiggyP* mInfo;
};
#endif

// Code
// Always put the interface first. Helps in picking out dependencies
#include "Biggy.h"
#include "Medium.h"
#include "Small.h"

// Friend free zone: Everything is public since the interface
// only exists in the implementation
class BiggyP
{
public:
...
void SubOne ()
{
...
}

};

Biggy::Biggy ()
{
mInfo = new BiggyP();
}
Biggy::~Biggy ()
{
delete mInfo;
}

...
void Biggy::SubOne ()
{
mInfo->SubOne ();
}

Medium* Biggy::GetMedium ()
{
return mInfo->mMedium;
}


BiggyP will only be defined in the implementation and the include files for Medium and Small only need to be included in the Biggy implementation file and not the Biggy header file. The other advantage is that you can change the implementation as much as you like without having to modify the header file, causing massive rebuilds. It may seem silly to have a tie class but it stops the rebuilds and it does not create unnecessary dependencies.

Just using the above techniques, I managed to reduce the build time of one system from 5 hours to 80 minutes and another one from 28 hours to 11 hours.

//JP added flex table