?
Solved

Visual C++ Linker error

Posted on 2003-03-23
4
Medium Priority
?
698 Views
Last Modified: 2012-05-04
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
Comment
Question by:Kashra
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
  • 2
4 Comments
 
LVL 48

Expert Comment

by:AlexFM
ID: 8189497
#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
 
LVL 3

Author Comment

by:Kashra
ID: 8190775
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
 
LVL 48

Accepted Solution

by:
AlexFM earned 100 total points
ID: 8193313
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
 
LVL 3

Author Comment

by:Kashra
ID: 8206355
Thanks, I think I understand it a bit better now.
0

Featured Post

On Demand Webinar - Networking for the Cloud Era

This webinar discusses:
-Common barriers companies experience when moving to the cloud
-How SD-WAN changes the way we look at networks
-Best practices customers should employ moving forward with cloud migration
-What happens behind the scenes of SteelConnect’s one-click button

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.
Suggested Courses
Course of the Month12 days, 15 hours left to enroll

777 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question