0

Possible Duplicate:
C header file loops

Original Question:

I always had problems understanding why the following gives errors:

something.h

#ifndef SOMETHING_H
#define SOMETHING_H

#include "somethingelse.h"

#endif

somethingelse.h

#ifndef SOMETHINGELSE_H
#define SOMETHINGELSE_H

#include "something.h"

#endif

Why does this give errors?

1) SOMETHING_H is not defined

2) SOMETHING_H becomes defined, somethingelse.h get included

3) SOMETHINGELSE_H is not defined, becomes defined, and something.h gets included

4) SOMETHING_H is defined, jump to #endif, this should be the end of it?


EDIT:

turns out it doesn't give any errors at all. However the following does:

something.h

#pragma once

#include "somethingelse.h"

class something {
    int y;
    somethingelse b;
};

somethingelse.h

#pragma once

#include "something.h"

class somethingelse {
    something b;
    int x;
};

And it is logical, because the class 'something' is not yet defined when 'somethingelse' needs an instance of that class.

The problem is solved by forward definition:

something.h

#pragma once

class somethingelse;

class something {
    int y;
    somethingelse* pB; //note the pointer. Correct me if I'm wrong but I think it cannot be an object because the class is only declared, not defined.
};

in the .cpp, you can include "somethingelse.h", and make instances of the class.

Community
  • 1
  • 1
xcrypt
  • 3,276
  • 5
  • 39
  • 63
  • 3
    That code shouldn't error at all...what are you getting? – VolatileDream Oct 30 '11 at 18:43
  • Wait, what, this doesn't give me errors O.o In school I learned that include guards don't protect against endless include cycles O.o. Only in cases where file A includes B and C, and where file B includes C, it would only include C once. Hmm – xcrypt Oct 30 '11 at 18:56
  • 1
    He has incomplete types he isn't showing. – Brian Roach Oct 30 '11 at 19:05

2 Answers2

1

Your description is exactly correct, except that there is no error at all. Add pragma message("Some text") (assuming Visual Studio) at various places to trace the flow.

As other posters have already noted, your header files most likely contain classes that mutually require each other's definition, and that is the cause of the problem. This sort of problem is usually solved by

  • Using forward references where possible
  • Moving #includes to CPP files where possible
Dabbler
  • 9,733
  • 5
  • 41
  • 64
  • Well why? Your suggestion is correct, and I know how to solve the problem, but why is it a problem that the classes require each other's definition? They only get included once so I don't see a problem? – xcrypt Oct 30 '11 at 19:00
  • 1
    Let's assume you compile `something.cpp`, which includes `something.h`. This leads you to assume the class definition of `Something` has been seen. But it hasn't, because the compiler branches off to `somethingelse.h` first. There, the class `Somethingelse` requires the definition of `Something`, and although it `#include`s `something.h`, that doesn't help because SOMETHING_H is already defined. – Dabbler Oct 30 '11 at 19:23
0

That's exactly what happens.

This is called an "include guard" and is used to avoid infinitely recursive includes.

VolatileDream
  • 1,083
  • 7
  • 15