Question

Is there any valid reason for placing #include directives BEFORE the include guards in a header file like this:

#include "jsarray.h"
#include "jsanalyze.h"
#include "jscompartment.h"
#include "jsgcmark.h"
#include "jsinfer.h"
#include "jsprf.h"
#include "vm/GlobalObject.h"

#include "vm/Stack-inl.h"

#ifndef jsinferinlines_h___
#define jsinferinlines_h___

//main body mostly inline functions 

#endif

Note, this example is a taken from a real life high profile open source project that should be developed by seasoned programmers - the Mozilla Spidermonkey open source Javascript engine used in Firefox 10 (the same header file also exists in the latest version).

In high profile projects, I expect there must be some valid reasons behind their design. What are the valid reasons to have #include before the include guard? Is it a pattern applicable to inline-function-only header files? Also note that this header file (jsinferinlines.h) is actually including itself through the last #include "vm/Stack-inl.h" (this header file includes a lot of other headers and one of them actually includes this jsinferinlines.h again) directive before the include guard, this makes even less sense to me.

Was it helpful?

Solution 2

There were lots of include cycles in SpiderMonkey headers back then, and placing the header guard at the top caused difficult to understand compile errors - I suspect that putting the header guard below the includes was just an incremental step toward sanitizing the includes.

I couldn't tell you the exact sequence of includes that caused it to make a difference, though.

Nowadays there shouldn't be any include cycles in SM headers, and their style is enforced through a python script written by Nicholas Nethercote. If you look at jsinferinlines.h today you'll see the header guard is at the top where it belongs.

OTHER TIPS

Because you expect those headers to have include guards of their own, therefore it doesn't really make any difference.

Also note that this header file (jsinferinlines.h) is actually including itself through the last #include "vm/Stack-inl.h" (this header file includes a lot of other headers and one of them actually includes this jsinferinlines.h again) directive before the include guard, this makes even less sense to me.

It won't make any different because the workflow, when including that file, will be:

  • include all header up to "vm/Stack-inl.h"
  • include the "vm/Stack-inl.h" up to the last #include "jsinferinlines.h" (your file)
  • include the file jsinferinlines.h again (skipping all the previous includes, because include guards)
  • reach past #include "vm/Stack-inl.h"
  • finally process from #ifndef jsinferinlines_h___ on

But in general, mutual header recursion is bad and should be avoided at all costs.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top