4

So I read up on the ordering of your includes, and this guy suggested you include your local header first so as to make sure it doesn't have prerequisites. Ok, I get that. I'm on board. The whole compartmentalization thing is good.

But I've got this file, file.c which includes it's file.h, which declares functions to save files. Which passes around the FILE* type used by fopen and friends.

If I include file.h before I include stdio.h then there's an obvious parsing error when it's building file.h because it doesn't know about the FILE* type.

I know I've got to be missing something dirt simple, but I can formulate this into something google can use. Should I be doing something different in file.h? Is this simply something that needs to be included in a specific order? Thoughts?

1 Answer 1

11

If a header file such as file.h depends on other headers such as stdio.h, then file.h should #include those headers as necessary.

Each header file should keep track of its own dependencies, and use #include guards to prevent multiple translation if it winds up being included several times:

#ifndef FILE_H
#define FILE_H

#include <stdio.h>
...
void myfunc(FILE *);
...
#endif

This way the order of the includes simply doesn't matter, which makes maintenance much less crazy-making.

7
  • Macro guarding is always that way to go for things like this. Just make sure you don't accidentally double up on the macro guard names.
    – ardent
    Jul 18, 2012 at 17:31
  • 3
    I've seen arguments that headers should not #include headers that they depend on; rather, that the .c file should directly include everything that its headers depend on, in the correct order. These arguments, IMHO, are wrong. Jul 18, 2012 at 17:49
  • 2
    @KeithThompson: The people making those arguments obviously haven't wasted the better part of an afternoon trying to get 15 to 20 different headers in just the right order to get something to compile (with no documentation, naturally).
    – John Bode
    Jul 18, 2012 at 18:13
  • @JohnBode: As I recall, the argument had to do with avoiding the overhead of scanning headers multiple times. Even with include guards, it does take some time to read a header file. The argument was more valid in the past, with slower machines -- but even then I'm skeptical that the time saved in compilation would exceed the time wasted keeping all the dependencies straight. Jul 18, 2012 at 18:26
  • 1
    @JohnBode: I believe most modern compilers explicitly recognise the "include guard" pattern the first time the file is scanned, and cache that fact to avoid having to scan the same include file repeatedly. Jul 18, 2012 at 19:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.