Headers inclusion

While implementing my Virtual File System I faced a common tricky problem: headers inclusion. There are mainly two ways of including headers in c++:
- Never include headers in headers,
- Include headers in headers so that each one is completely autonomous i.e. when you want to use a header, you don't have to include other files.

I have chosen the first solution for the following reasons:
- Compilation should be faster,
- Headers are more readable,
- It forces me to use forward declaration as much as possible.

In each library I always have the 3 following header files:
- Precompiled header containing external includes i.e. standard C/C++ and external libraries headers,
- Header containing headers from the library which are commonly used by the library itself. I didn't put them in the precompiled header because of a Visual Studio bug which makes debuging harder,
- Header containing headers from the library which can be used by other libraries i.e. some kind of interface.

But this way of including headers has several problems:
- It's sometimes hard to identify dependancies between headers,
- When you want to include one file, you have to include others,
- You often have inter inclusion issues.

For all these reasons I decided to change the way I include files. Hopefully, my code base was small and it took me only 3 hours of pain (many compilation errors to solve) to do the modications. As a result, my libraries are clearer and easier to use.

Now, I don't need the header file containing headers which can be used by other libraries since all headers are autonomous.

While I was modifying my source code I also realised that some of my headers were polluted by conditions on platform.

#if defined(PLATFORM_WIN32)
// ...
#elif defined(PLATFORM_LINUX)
// ...
#else
// ...
#endif

That's the reason why I decided to change the layout of my projects. Before, my libraries was organised this way:
MyLib\
     Sources\
             XX.cpp
             XX.h
             SubDir\
                   YY.cpp
                   YY.h

I have modified them this way:
MyLib\
     Sources\
             Common\
                   XX.cpp
                    XX.h
                    SubDir\
                        YY.cpp
                        YY.h
             PlatformSpecific\
                   Win32\
                        ZZ.cpp
                        ZZ.h
                        SubDir\
                           WW.cpp
                           WW.h
                   Windows\
                        RR.cpp
                        RR.h
                        SubDir\
                           TT.cpp
                           TT.h

And I also created macro to include these files easily from platform independant source code:

#define LIB_PLATFORM_INCLUDE(Lib,RelPath)          <Lib/Sources/PlatformSpecific/PLATFORM/RelPath>
#define LIB_PLATFORM_FAMILY_INCLUDE(Lib,RelPath)   <Lib/Sources/PlatformSpecific/PLATFORM_FAMILY/RelPath>


For example, to unclude file ZZ.h from platform independant code, I simply have to write:

#include LIB_PLATFORM_FAMILY_INCLUDE(MyLib,ZZ.h)

Now, I have no condition on target platform in platform independant source code.

I don't know if it will help someone but it was my exprerience with files inclusion ^^. Now I can go back to the implementation of my virtual filesystem :).

---
Manu




Article ajouté le 2009-07-19 , consulté 53 fois

Commentaires



Poster un commentaire





http://





Merci de recopier le nombre présent à gauche dans la case de texte ci-dessous ( Pourquoi ? )





Liens

Voir les articles de la catégorie " Programmation "

Retour aux articles



Recommander ce blog | Contacter l'auteur | Reporter un abus | S'abonner au blog Flux RSS du blog | Espace de gestion

Créer un blog gratuit avec Blog4ever