Problem with including header files

Started by
12 comments, last by Zeraan 18 years, 9 months ago
Yes, I've included inclusion guards. Here's the source code:

////////////////////////////////////////////////////////////////////////////GameMain.h////////////////////////////////////////////////////////////////////////////#ifndef GAMEMAIN#define GAMEMAIN#include <windows.h>#include "C:\Games\Brent's Games\Outpost\Outpost.h"bool Game_Init(/*TOutpost_Graphic, */HWND, int, int);bool Game_Main();void Game_End();#endif////////////////////////////////////////////////////////////////////////////GameInit.cpp////////////////////////////////////////////////////////////////////////////#include <windows.h>#include "C:\Games\Brent's Games\Outpost\Outpost.h"bool Game_Init(/*TOutpost_Graphic Graphic, */HWND hWnd, int Width, int Height){	if(!Graphic.D3D_Init(hWnd, 800, 600))		return false;	return true;}////////////////////////////////////////////////////////////////////////////WinMain.cpp////////////////////////////////////////////////////////////////////////////#define WIN32_LEAN_AND_MEAN#define DIRECTINPUT_VERSION 0x0800#include <windows.h>#include "GameMain.h"...TOutpost_Graphic Graphic;...int WINAPI WinMain(HINSTANCE hInstance,					 HINSTANCE hPrevInstance,					 LPSTR lpCmdLine,					 int nCmdShow){	...         if(!Game_Init(Graphic, g_hWnd, 800, 600))             //error message}...////////////////////////////////////////////////////////////////////////////Outpost.h////////////////////////////////////////////////////////////////////////////#ifndef OUTPOST#define OUTPOST#include <d3d8.h>#include <d3dx8.h>#include <dinput.h>#include <dplay8.h>#include <dpaddr.h>#include "OutpostG.h" //Graphic#include "OutpostI.h" //Input#endif////////////////////////////////////////////////////////////////////////////OutpostG.h (there's no Outpost.cpp)////////////////////////////////////////////////////////////////////////////#ifndef OUTPOSTG#define OUTPOSTG#include <d3d8.h>#include <d3dx8.h>#include "Outpost.h"#include "TParticle.h"#define WThinLine_FVF (D3DFVF_XYZ | D3DFVF_DIFFUSE)#define SThinLine_FVF (D3DFVF_XYZRHW | D3DFVF_DIFFUSE)#define PolyObject_FVF (D3DFVF_XYZ | D3DFVF_TEX1)#define POINT_LIGHT 0#define DIRECTIONAL_LIGHT 1class declarations from this point....#include "OutpostG.cpp"#endif////////////////////////////////////////////////////////////////////////////OutpostI.h////////////////////////////////////////////////////////////////////////////#ifndef OUTPOSTI_H#define OUTPOSTI_H#include <dinput.h>#include "Outpost.h"#define LEFT_BUTTON		0#define RIGHT_BUTTON	1#define MIDDLE_BUTTON	2#define MouseButtonState(x) ((m_MouseState.rgbButtons[x] & 0x80) ? TRUE : FALSE)class TOutpost_Input {private:		UCHAR keystate[256];	DIMOUSESTATE m_MouseState;	int m_MouseXPos, m_MouseYPos;	LPDIRECTINPUT8 m_lpdi;				// direct input object		LPDIRECTINPUTDEVICE8 m_lpdikey;	LPDIRECTINPUTDEVICE8 m_lpdimouse;public:	TOutpost_Input();	~TOutpost_Input();	bool DI_Init(HINSTANCE, HWND);	void DI_End();	bool KeyDown(int n);	int MouseXPos();	int MouseYPos();	bool MouseDown(int);	bool UpdateKeyboard();	bool UpdateMouse(int, int, HWND, bool Windowed = false);};#include "OutpostI.cpp"#endif


I don't know how to do code blocks. But this is my code.
Advertisement
Quote:Original post by Xai


please post a post with a little tree showing what files are including what ...


Ok, I should have done that. Sigh... ok here it is:

Engine, aka the Outpost:
Outpost.h - includes OutpostG.h and OutpostI.h
OutpostG.h - includes Outpost.h, TParticle.h and OutpostG.cpp.
OutpostI.h - includes Outpost.h and OutpostI.cpp
TParticle.h - includes OutpostG.h and TParticle.cpp

each of the .cpp files includes their own .h file, not Outpost.h

The game:
GameMain.h - includes Outpost.h
WinMain.cpp - includes GameMain.h
GameInit.cpp - includes GameMain.h

The Outpost files aren't included in the workspace, they're external dependences.
Quote:Original post by Zeraan
Ok, I should have done that. Sigh... ok here it is:

Engine, aka the Outpost:
Outpost.h - includes OutpostG.h and OutpostI.h
OutpostG.h - includes Outpost.h, TParticle.h and OutpostG.cpp.
OutpostI.h - includes Outpost.h and OutpostI.cpp
TParticle.h - includes OutpostG.h and TParticle.cpp


Bad! Don't include the .cpp from the header. The definitions are needed (from .h) for the declarations (.cpp), but NOT the other way around. Include guards protect you from multiple inclusion *within* a compilation unit; they can't protect you from multiple definitions between units (i.e. one in each unit).

Here, what happens is:

- Compiling Outpost.cpp: OutpostG.h gets included. This attempts to include Outpost.h (skipped by include guard), then TParticle.h. TParticle.h tries to include OutpostG.h (skipped by include guard) and TParticle.cpp - at this point, all the definitions of TParticle stuff get added to this compilation unit. Then OutpostG.h includes OutpostG.cpp, which brings in those definitions as well. Finally, the Outpost stuff itself is present in that unit.

- Compiling OutpostG.h: Similarly, you get TParticle in here. Actually, this only even *compiles* because you presumably have an include guard on the .cpp file as well.

- etc.

- Finally we get to linking, and the linker gives up, because these four .o files it's been given - Outpost.o, OutpostG.o, etc. have multiple definitions of TParticle stuff (and other stuff too) between them. They're actually not necessarily even identical (because of compiler optimizations), and even if they were, the linker would not be able to accept it - it's trying to match up all the calls to TParticle functions to implementations of said functions, and for any given call, there are multiple choices - this violates the so-called "One Definition Rule".

In short: Don't include .cpp files! Oh, and read this already.. :)


Thanks! I really appreciate that link! Fixed the problem!

This topic is closed to new replies.

Advertisement