How can I avoid the LNK2005 linker error for variables defined in a header file?

28,190

Solution 1

Keep in mind that a #include is roughly like cutting and pasting the included file inside the source file that includes it (this is a rough analogy, but you get the point). That means if you have:

int x;  // or "slider" or whatever vars are conflicting

in the header file and that header file is included by three source files in a program, then they will all have a global named x defined that will conflict.

What you want to do is define the variable as extern so that the .cpp files will all get the declaration, and then in ONE of your .cpp files give the actual definition.

in Variables.h:

extern int x;

in SomeSourceFile.cpp

int x;

Of course, I'd recommend against globals, but if you must use them this would keep them from conflicting.

Solution 2

Because "int slider" is already defined in another file? Check that you have header guards...

#ifndef _VARIABLES_H_
#define _VARIABLES_H_

int slider;

#endif

If it is across multiple translation units, and you do want the variables to be different (ie not global), then maybe declare them in an anonymous namespace:

namespace {
    int slider;
}

If you do want them global, look to James' solution.

Solution 3

This is because the compiler compiles each .cpp file separately, creating a .obj file for each one. Your header appears to have something like:

int slider;

When this is included into each of your three .cpp file, you get three copies of the int slider variable, just as if you had declared it in each .cpp file. The linker complains about this because you haven't have three different things with the same name.

What you probably want to do is change your header file to read:

extern int slider;

This tells the compiler that there is a slider variable somewhere, but possibly not here, and lets the linker figure it out. Then, in one .cpp file:

int slider;

gives the linker one actual variable to link.

Solution 4

I know that this is an old thread, but I came across this as one of the first search results from Google. I solved the problem by placing the variable static.

namespace Vert
{
   static int i;
}

I tried extern and in my situation that didn't seem to solve the problem.

Solution 5

What is happening is that each of the variables from Variables.h are given global scope for each of the individual c files. When the linker compiles all the c files, it sees multiple variables with the same name.

If you are wanting to use variables from the header file as global variables, then you will have to use the keyword "extern" in front of all of them, and in the main file don't use the keyword extern.

main c:

int n_MyVar;

other files:

extern int n_MyVar;

You can create two files Variables.h and EVariables.h, or just declare the variables in the main.cpp file.

A much better way to do this is to create a class of Variables and pass a reference to the class.

Share:
28,190
Mark Lalor
Author by

Mark Lalor

I began my programming journey at the age of 11. My 5th grade teacher showed me that I could save a file on notepad with another file extension than .txt! Thus began my interest in HTML, CSS, Javascript, PHP, PHP GD, jQuery, SQL, C#, .NET Framework, C, C++, mobile apps, DragonFireSDK (7/10 would not use again), Objective C, and Java, in that order. I learned only through books and the internet, which is why I asked many dumb questions years ago. I like to look back on them and reminisce on my bad programming skills and problem-solving.

Updated on April 28, 2020

Comments

  • Mark Lalor
    Mark Lalor about 4 years

    I have 3 cpp files that look like this

    #include "Variables.h"
    void AppMain() {
        //Stuff...
    }
    

    They all use the same variables inside them so they have the same headers but I get stuff like this

    1>OnTimer.obj : error LNK2005: "int slider" (?slider@@3HA) already defined in AppMain.obj
    

    Why is that?

  • Greg Hewgill
    Greg Hewgill about 13 years
    Header guards won't help here, since the cpp files are compiled separately.
  • deceleratedcaviar
    deceleratedcaviar about 13 years
    I gave a solution to that. Check fixed answer.
  • Greg Hewgill
    Greg Hewgill about 13 years
    @Mark: While using a namespace will compile, it probably won't do what you want. If you want the same variable to be used across all your source files (so that changes in one file are visible in another file), the above solution won't do that.
  • James Michael Hare
    James Michael Hare about 13 years
    Yep, if you want each .cpp file to have independent slider variable, use this solution, if you want all the .cpp files to share the same slider variable, use the extern method below.
  • Mark Lalor
    Mark Lalor about 13 years
    Yeah I need to use the same values... changed accepted answer