Sign in to follow this  
instinKt

#include order standard?

Recommended Posts

So I'm working through my code and I remember a great tool for detecting memory leaks, Paul Nettle's mmgr and decide to stick it in to make sure everything is okay. It went well, but for it to work properly the header needs to be included in a specific order which I tried to abide but it would mean making some major changes to the includes I have and possibly project wide headers that are included in every file etc etc. So this got me thinking, is there any sort of standard or "good practice" methods to where to include your headers. Currently I include standard headers before any of my own, and in every .h and .cpp file I include what I need. Eg. if the header has a class with a vector member then ill include <vector> in the header and in the .cpp also. I had a quick look around and didn't see any references at a first glance, but as I'm at work I don't really have time for an in depth look and thought it would be interesting to see other peoples views.

Share this post


Link to post
Share on other sites
I use MMGR in my project to debug my memory management as well ;)

Every one of my cpp files (indirectly/directly) includes a file called "core.h", which contains some standard stuff (typedef unsigned int uint; etc...). So I just include MMGR inside "core.h" and everything includes it. Any standard headers get included prior to including "core.h" so that MMGR doesn't screw with the standard libraries.

Quote:
Original post by instinKt
It went well, but for it to work properly the header needs to be included in a specific order which I tried to abide but it would mean making some major changes to the includes I have and possibly project wide headers that are included in every file etc etc.

If you have a project wide header that's included in every file, put the MMGR include in that header!

Quote:
Original post by instinKt
So this got me thinking, is there any sort of standard or "good practice" methods to where to include your headers. Currently I include standard headers before any of my own, and in every .h and .cpp file I include what I need.

I usually have a header paired with every cpp file. The cpp file includes the header of the same name, as well as any headers that are needed by the implementation (but aren't needed by the declaration). The header contains all the includes needed by the declaration.

e.g. In (1) "bar.h" is required in the declaration, so must be included in the Foo header. In (2) "bar.h" is only required by the implementation, so is included in the Foo CPP file only.

1)
include "bar.h"
class Foo
{
Foo();
Bar myMember;
}

2)
class Bar;
class Foo
{
Foo();
Bar* myMember;
}


Quote:
Original post by instinKt
Eg. if the header has a class with a vector member then ill include <vector> in the header and in the .cpp also.

Whats the point of putting it in the cpp if it's already in the header?

Share this post


Link to post
Share on other sites
Quote:
Original post by Hodgman
Quote:
Original post by instinKt
It went well, but for it to work properly the header needs to be included in a specific order which I tried to abide but it would mean making some major changes to the includes I have and possibly project wide headers that are included in every file etc etc.

If you have a project wide header that's included in every file, put the MMGR include in that header!

I don't have a project wide header currently and usually steer away from it unless I really need it. I think it's an attempt subconsciously to keep some loose-coupling. :P
Quote:

Quote:
Original post by instinKt
Eg. if the header has a class with a vector member then ill include <vector> in the header and in the .cpp also.

Whats the point of putting it in the cpp if it's already in the header?

You know I just asked myself the exact same question not five minutes ago. The answer? Dunno, I've just always done that. I'm sure there's some long lost logic to it somewhere however. ;)

My problem is that I have a scenario something like this...
(core is the entry point of my app)

in core.cpp

#include <[standard headers]>
#include "mmgr/mmgr.h"
#include "core.h"
#include "window.h"

...


Then in core or window I might have included some more standard headers which is giving me many compile errors.

Now in trying to fix this problem I'm thinking I shouldn't include any standard headers in my own headers and simply include the standard headers in a related .cpp file before including this header itself. If that makes sense.

It sounds somehow evil to me.

Share this post


Link to post
Share on other sites
Personally I usually end up with an application-wide header. Luckily there's usually very little that needs to go into it, and things like debug-only hooks to a memory manager is exactly the sort of thing it might contain.

Share this post


Link to post
Share on other sites
The order I use varies from project to project. I lack discipline.

Usually it'll be:

1. standard library includes
2. stable/external library includes (e.g. boost, GUI toolkit, etc, "standard" as far as my applications are concerned)
3. my own headers

However, there is one reasonably important exception to this order.

I'll always #include "X.h" before anything else in X.cpp.

This is to make sure that nothing is missing from the interface provided by X.h i.e. all necessary #includes and forward declarations have been made in X.h.

If something is missing, we'll get a compiler error that we might not have otherwise seen if we put it further down the list.

This is important when preparing X.h as a header for a stand-alone library. You don't want someone else #including it and getting weird compiler errors.

Quick example:


// a.h
#ifndef A_H_2317_04062007
#define A_H_2317_04062007

typedef int gizmo_t;

#endif




// b.h
#ifndef B_H_2317_04062007
#define B_H_2317_04062007

gizmo_t f();

#endif



Now any file that includes a.h before b.h will compile fine. Reverse the order or remove a.h entirely and the compiler will barf. If you distributed b.h as part of a library, clients should reasonably be able to expect any header to be #include-able without getting a compiler error.

Edd

Share this post


Link to post
Share on other sites
There might be multiple b.h files in the project. By putting on a time stamp or some other hash you reduce the chance of conflicts.

And yes such conflicts do happen. They have to me anyway. It took a while to find out why some stuff wasn't declared to the compiler.

In fact I usually prepend the library/module name too:
LIBNAME_FILENAME_HPP_TIME_DATE

It's long, but who cares when a script/editor does it for you?

Edd

Share this post


Link to post
Share on other sites
My own ad hoc ordering:

#include <project name/*/import.hpp>
#include <project name/*/*.hpp>
#include <boost/*.hpp>
#include <iostream, limits, other standard C++ library headers>
#include <cstdio, cstdlib, other C++ified legacy C library headers>


Aside from boost and C++ standard library headers, I usually toss groups of related includes into an import.hpp file which I make a point to include before anything else. This file takes care of platform differences (e.g. <GL/gl.h> versus <OpenGL/gl.h> on OS X), macro pollution cleanup (e.g. #undef main in SDL.h, a #define NOMINMAX before <windows.h>), and makes for a handy place to put anything needing to be "first" at.

Aside from that, most of the structure is just to try and keep things a bit organized for myself. I tend to alphabetize within given categories as well.

Share this post


Link to post
Share on other sites
These days I always create an application-specific header, just because it's almost always eventually useful. I understand the desire to keep away from that, to reduce coupling between source files, but C++ is an ugly, hackish language which often requires ugly, hackish things to be all it can be, many of which demand to be placed before other files.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this