Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 699
  • Last Modified:

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?
0
Kashra
Asked:
Kashra
  • 2
  • 2
1 Solution
 
AlexFMCommented:
#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.


0
 
KashraAuthor Commented:
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?
0
 
AlexFMCommented:
You declare global variable in h-file as extern if you want to use it in more that one cpp file. Variable itself (without extern) is declared in one cpp file.

There is no need to declare global variable in h-file if it is used in only one cpp file.

Your definition of extern keyword is right.

Global variable with static keyword has module scope. If such variable is declared in number of cpp files, there are number of different variables. So, if you write in h-file:

static int x;

this solves your compilation problems, but by unpredictable way: each cpp file where h-file is included has it's own x variable.
0
 
KashraAuthor Commented:
Thanks, I think I understand it a bit better now.
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

  • 2
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now