Linker issue

I have been trying to break up my program into multiple source files and header files, except I run into a problem. One of my variables has to be included into multiple source files, so I placed it into a header file and #included those headers into the appropriate files. But, no matter what I try it either: does not get referenced in the correct files, or it gets referenced multiple times. I've tried http://www.gamedev.net/reference/articles/article1798.asp which is an excellent source on organizing your files, and fixing some common errors, but none of the solutions seems to fix the problem.

#ifndef makes the linker have an error, while it's absence makes the compiler find the redefinition error. If I use the extern keyword, the files don't get referenced in some files, but if I don't, it gets referenced many times.

Here are the errors without the extern keyword and #ifndef surrounding the variable:

1
2
3
4
5
6
7
1>Input.obj : error LNK2005: "int mainMenuCursorPos" (?mainMenuCursorPos@@3HA) already defined in DirectX.obj
1>Main.obj : error LNK2005: "int mainMenuCursorPos" (?mainMenuCursorPos@@3HA) already defined in DirectX.obj
1>Render.obj : error LNK2005: "int mainMenuCursorPos" (?mainMenuCursorPos@@3HA) already defined in DirectX.obj
1>Input.obj : error LNK2001: unresolved external symbol "struct tagPOINT MousePos" (?MousePos@@3UtagPOINT@@A)
1>Render.obj : error LNK2019: unresolved external symbol "void __cdecl RenderMainMenuPlayNotSelected(void)" (?RenderMainMenuPlayNotSelected@@YAXXZ) 
referenced in function "void __cdecl Render_Frame(int)" (?Render_Frame@@YAXH@Z)
1>C:\Documents and Settings\Owner\my documents\visual studio 2010\Projects\Practice\Debug\Practice.exe : fatal error LNK1120: 2 unresolved externals


This has been confusing me for a while, any help would be very appreciated =).

*EDIT*: broke the page.
Last edited on
globals are evil.

globals in header files are especially evil.

You're getting these errors because you have a global in a header file, and that header file is included in multiple cpp files. Since #include is basically a copy/paste operation, this means that each source file is defining its own variables with those names. Then the linker gets confused because it has all these duplicate variable names and it doesn't know which one to use.

The solution here is to not use globals (or at least avoid them). Heavy use of globals is a tell tale sign of terrible design.


If you must use globals, you can get around the problem with the extern keyword:

1
2
3
4
5
extern int foo;  // tells the compiler that a variable named foo exists somewhere
  // without actually generating a variable

// vs. 
int foo;  // tells the compiler that the variable exists AND generates that variable. 


In practice, you would put the non-extern var in one and only one cpp file, and the extern in a header:

1
2
// globals.h
extern int myglobal;
1
2
3
// globals.cpp

int myglobal;



But this makes it so you have to duplicate all the variable declarations (one in the header and again in the cpp, and both must match). To avoid that, you can use #define magic to cheat:

1
2
3
4
5
6
// globals.h
#ifndef GLOBAL
#define GLOBAL extern
#endif

GLOBAL int myglobal;
1
2
3
//globals.cpp
#define GLOBAL
#include "globals.h" 
1
2
//all_other_cpp_files.cpp
#include "globals.h" 



EDIT:

That will solve your first 3 erorrs anyway. As for the last 2:

1>Input.obj : error LNK2001: unresolved external symbol "struct tagPOINT MousePos" (?MousePos@@3UtagPOINT@@A)

This is telling you that you didn't define your MousePos struct. Either that or you're not linking to the cpp file that defines it.

1
2
1>Render.obj : error LNK2019: unresolved external symbol "void __cdecl RenderMainMenuPlayNotSelected(void)" (?RenderMainMenuPlayNotSelected@@YAXXZ) 
referenced in function "void __cdecl Render_Frame(int)" (?Render_Frame@@YAXH@Z)


Similarly, this is telling you that you didn't give your RenderMainMenuPlayNotSelected function a body. That or you didn't link to the file that contains the body.
Last edited on
Yes, I realize this and I've tried using the extern keyword. But, if the variable being global is the problem, then how would I use a variable in more than one source file if that's required?
Yes, I realize this and I've tried using the extern keyword. But, if the variable being global is the problem, then how would I use a variable in more than one source file if that's required?
How do I do this if that's required?
Did you read my post? =P

1
2
3
// in globals.h

extern int myglobal;

1
2
3
// in globals.cpp

int myglobal;

1
2
3
// in whatever cpp file you want to have access to the globals

#include "globals.h" 
Last edited on
Aahhh! Ok, I guess I just don't know how to use extern, lol...I didn't know you had to reference it again in a CPP file. Thanks, that fixed it. And yes, I did read your post, =P.
Topic archived. No new replies allowed.