2

If every header uses #ifndef does this mean compiler errors regarding a circular dependency will not happen?

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
user997112
  • 29,025
  • 43
  • 182
  • 361
  • 1
    No, it doesn't mean that. You can easily engineer circular dependencies. Just try it. – juanchopanza Jan 16 '14 at 16:51
  • 1
    Matthieu's answer on [this question](http://stackoverflow.com/questions/3127171/how-are-circular-includes-resolved/3127374#3127374) explains the difference between the two problems quite nicely. – starsplusplus Jan 16 '14 at 16:53

2 Answers2

4

No, it does not.

It means the compiler won't try to include headers for infinity, but a circular dependency still poses a logical problem, because compilation is performed from top to bottom. Let's take a little look at why:


Source code

a.h

#ifndef A_H
#define A_H

#include "b.h"

struct A
{
   B* ptr;
};

#endif

b.h

#ifndef B_H
#define B_H

#include "a.h"

struct B
{
   A* ptr;
};

#endif

main.cpp

#include "a.h"

int main()
{
   A a;
}

After preprocessor runs

The include guards enable us to actually run the preprocessor and have it finish its work in less-than-infinity time; so fast, actually, that I've done it by hand below. The result is:

struct B
{
   A* ptr;
};

struct A
{
   B* ptr;
};

int main()
{
   A a;
}

The definition of B comes before the definition of A, so that A* ptr; cannot be understood. Sure, you can fix that, but only by reversing the order of inclusion, and then you have the opposite problem. Forward declarations and/or re-architecture are the only ways to resolve it.

Header guards solve a different problem. They do not allow you to simply do whatever you like.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • Is it fair of me to wonder- whats the point of it then if it doesnt fix the problem? – user997112 Jan 16 '14 at 16:52
  • @user997112 it doesn't fix *this* problem - it solves multiple definitions though. – Luchian Grigore Jan 16 '14 at 16:53
  • The point of it is explained quite well [here](http://stackoverflow.com/questions/3127171/how-are-circular-includes-resolved/3127374#3127374). :) – starsplusplus Jan 16 '14 at 16:54
  • 2
    @user997112: include guards prevent multiple definition errors if the same header file gets `#include`d more than once per translation unit (for example, `bar.c` includes `bar.h` and `foo.h`, and `bar.h` also includes `foo.h`, so `foo.h` will be processed twice). – John Bode Jan 16 '14 at 17:02
0

It will not create any circular dependency, it will include the file multiple times as the name 'include' says. This usually happens when the code base is big and the we dont know if this file is already included by another header file.

We can also use a single statement , #pragma once

vathsa
  • 303
  • 1
  • 7