Anonymous
Anonymous

Reputation: 4197

Should you rely on another header for the headers it includes?

Assuming that all headers are guarded, let's say you had an abstract data type.

#include "that.h"
#include "there.h"

class Foo {
 protected:
  // Functions that do stuff with varOne and varTwo
 private:
  that varOne; 
  there varTwo;
 ...
};

Then in the classes that inherit from foo ( and thus include foo.h ), would you also bother including that and this? Normally what I do is include everything that a class needs, regardless of whether would already receive them from another include. Is this redundant?

Upvotes: 3

Views: 676

Answers (6)

Crashworks
Crashworks

Reputation: 41482

There is one downside to redundantly including header files that would otherwise have been included directly: it forces the compiler to reopen and reparse them. For example, in

a.h:

#ifndef __A_H
#define __A_H
// whatever
#endif

b.h:

#ifndef __B_H
#define __B_H
#include "a.h"
// whatever
#endif

c.cpp:

#include "a.h"
#include "b.h"
//whatever

a.h has to be opened and read twice -- although the #ifndef will make the preproc ignore a.h's contents in the second inclusion, it still has to at least load the file from disk and read its bytes from the #ifndef to the #endif.

This can slow down compilation. It will not break your build or anything though, it'll just be an annoyance in really large projects, where compiles can take many minutes.

If you use #pragma once in your headers, there's a good chance an aware compiler will cache the filenames at a higher level, and ignore the second inclusion of a.h altogether. That too can speed up builds.

Upvotes: 3

Charles Ma
Charles Ma

Reputation: 49211

It's not necessarily redundant. The fact that you have separate header files and source files means that you can swap src and header files around as long as the source files provide definitions for the header files.

The .h file should include only things that are used in the header. It doesn't need stdio for example if there are no io declarations in the header, instead it should only go in the src file if it is using printf for example.

But there might be situations where one header you can use will need a particular include, while another header won't (e.g. when one header is a more restrictive interface than the other), in which case it's better to duplicate the .h includes.

Since it's guarded, it really makes no difference to the final object/exe you produce, and it doesn't increase compile time by anything worth worrying about, so it's better to include them just in case you want to use a different .h file at some point.

edit: more concrete example inc1.h

#ifndef INC1_H
#define INC1_H
inc1_struct {                                                            
   int x;
};
#endif

inc2.h

#ifndef INC2_H
#define INC2_H
#include "inc1.h"
void inc2_f();
struct inc1_struct *inc2_callinc1();
#endif 

prog.cpp #include "inc1.h" #include "inc2.h"
#include #include

void inc2_f() {
   printf("inc2_f\n");
}

struct inc1_struct *inc2_callinc1() {
   return (struct inc1_struct*) malloc(sizeof(struct inc1_struct));
}

int main(int argc, char **argv) {
   struct inc1_struct *s = inc2_callinc1();
   return 0;
}

This would compile, but lets say you don't want to expose

struct inc1_struct *inc2_callinc1();

in inc2.h

Then you won't need to include inc1.h in the inc2.h file, but if you don't want to also delete the definition of inc2_callinc1() in prog.cpp, then you need to have included inc1.h.

Upvotes: 0

Charles Eli Cheese
Charles Eli Cheese

Reputation: 783

The problem is that you end up including extra things in your obj files this way. The header guards don't prevent this. Anything you reference must be in your object, so don't just have lots of headers including other headers then include that elsewhere. If you are sloppy with your headers and have many files you quickly get a bloated code size and slow compile time.

Upvotes: 1

NVRAM
NVRAM

Reputation: 7137

Then in the classes that inherit from foo ( and thus include foo.h ), would you also bother including that and this?

Typically I'll include headers (with guards) for any types the header uses directly.

However, I often drop that for a derived class where the base class must have included them because of member function prototypes that are overridden -- which is true for this and that in your example.

Ultimately it's your choice, but you may also consider how likely you think the headers are to ever change - since that's the only time it really matters.

Upvotes: 0

Don Neufeld
Don Neufeld

Reputation: 23238

In my experience, it's better to forward declare there and that in Foo.h rather than include them at all, since they are not technically needed given that they are passed by reference.

In that cade, Foo.h would look like:

class that;
class there;

class Foo
{
    public:

        void func( that &param ) = 0;
        void funcTwo( there &param ) = 0;
        ...
};

Upvotes: 1

Peter Alexander
Peter Alexander

Reputation: 54300

It's up to you really. If it's plainly obvious that the super class has included them (i.e. without looking at its header) then it would make sense to omit the #include. Of course, you are free to add them just to be safe.

Upvotes: 0

Related Questions