1

Possible Duplicate:
Why does this not prevent multiple function declarations?

Global.h

#ifndef Global_h
#define Global_h

#include <iostream>

unsigned char exitStatus;

#endif

OutputHandler.h

#ifndef OutputHandler_h
#define OutputHandler_h

#include "Global.h"

class OutputHandler {
private:
    static bool instanceExists;
// more code  

#endif

Root.h

#ifndef Root_h
#define Root_h

// declarations

OutputHandler *output;

#endif

Root.cpp

#include "Root.h"
// gets instance of OutputHandler
// more code

I am getting errors regarding exitStatus, static bool instanceExists, and static class output being already defined by Root.obj in OutputHandler.obj. I assume the issue is with including the header file OutputHandler.h in both Root.h and OutputHandler.cpp. Anyone know how to fix this or how to better organize header files?

Community
  • 1
  • 1
Kookehs
  • 84
  • 5
  • The answers to the Q explain why in detail. In short, You should not define objects in header file and then include that header in multiple TU's. It violates the ODR. – Alok Save Feb 01 '13 at 09:26

3 Answers3

4

Because include guards only work at the translation unit level (you can, for this simple case, consider a single C file to be a translation unit).

That means a single C file, if it includes the header file twice, will not process it the second time due to the include guards.

However, if you include the header from two different C files, each of them will get a copy of the variables defined in that header.

Then, when you link them together, you get the duplicates.

The easiest way to get around this problem is to never define things in headers, only declare them.

So, in the header (eg, xyzzy.h), you have:

extern int xyzzy;  // declare but don't define.

and in all the C files that want to use that, put:

$include "xyzzy.h"

and, in one of those C files, also put:

int xyzzy;        // define it here, once.

You can think of declaration as a simple "I declare that this exists somewhere, just not here", while definition is "I an creating this here and now".

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
2

Declare extern usigned char exitStatus in Global.h and define it in one implementation file.

Oswald
  • 31,254
  • 3
  • 43
  • 68
1

The problem is during the linking phase; include guards in the headers won't help you.

In C, there is the separate concepts of declarations and definitions. Declarations are what are put into headers; they merely state that a particular variable exists. The definition of a variable is where storage is actually allocated for it.

For example, in your Global.h, you have:

#ifndef Global_h
#define Global_h

#include <iostream>

usigned char exitStatus;

#endif

This is defining a variable called exitStatus, and the linker is complaining because any given variable should only be defined in one place in a program. What you need to do is declare it in the header, and then define it in only one place in a source (*.cpp) file. For example, your header should declare exitStatus with:

extern char exitStatus;

and in only one source file, define it with:

char exitStatus;

The situation is similar for output in Root.h, as well as any other place you should be declaring variables in the header file.

See also: http://www.cprogramming.com/declare_vs_define.html

sheu
  • 5,653
  • 17
  • 32