Link to home
Start Free TrialLog in
Avatar of Kashra
Kashra

asked on

Visual C++ Linker error

This should be a pretty easy one for most of you:

I have a Visual C++ .NET project with 4 files in it. 2 *.cpp and 2 *.h files.

file1.cpp:
//Contians WinMain, message loop, WndProc
#include "file1.h"
#include "file2.h"
[...]

file2.cpp:
// Contains some misc. functions
#include "file2.h"
[...]

file1.h:
// Contains a few global variables, and function declarations
// for functions in file1.cpp, plus other #includes for file1.cpp
#ifndef FILE1_H
#define FILE1_H
[...]
#endif

file2.h:
// Contains function declarations and globals for functions in
// file2.cpp
#ifndef FILE2_H
#define FILE2_H
[...]
#endif


So, what *I* expect out of this is that, whichever file gets compiled first will #include "file2.h", and the next #include for "file2.h" will pretty much be ignored because of the #ifndef statement. When I go to comple, though, I end up with the following:

error LNK2005: "[...]" already defined in file1.obj

where [...] represents everything that was declared in file1.h

If I remove file2.cpp from the project, and remove all calls for functions implemented in file2.cpp, the program compiles fine, but I don't understand why it has a problem with this setup. I'm not using pre-compiled headers or anything fancy. I'm surprised I haven't come across this before, since it seems like a really simple thing that I'm missing here. Any ideas?
Avatar of AlexFM
AlexFM

#ifndef works as expected. The problem is that you defined some global variables in h-file. h-file should contain variable declarations with extern keyword, and variable itself should be declared in only one cpp file:

// file1.h
#ifndef FILE1_H
#define FILE1_H

extern int g_nCounter;

#endif

// file1.cpp
#include "file1.h"
#include "file2.h"

int g_nCounter;


// file2.cpp
#include "file1.h"

// don't declare g_nCounter here !


h-file may contain:
1) global variables and objects with extern keywords
2) function prototypes (without bodies), like:

void MyFunction();

3) class definitions, enumerations and constants.


Avatar of Kashra

ASKER

Thanks. So my understanding of the extern keyword is that it tells the compiler "this is going to be defined elsewhere."

So what's the use of putting the global variables in the header file at all?

Also, I put "static" in front of the global variables in the header file and that seemed to make the error go away as well.  Why should that make a difference? Don't global variables have static duration anyway?
ASKER CERTIFIED SOLUTION
Avatar of AlexFM
AlexFM

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Kashra

ASKER

Thanks, I think I understand it a bit better now.