Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 394
Mark Lalor Avatar asked Apr 07 '11 00:04

Mark Lalor


3 Answers

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.

like image 153
James Michael Hare Avatar answered Sep 23 '22 21:09

James Michael Hare


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.

like image 32
Greg Hewgill Avatar answered Sep 24 '22 21:09

Greg Hewgill


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.

like image 23
deceleratedcaviar Avatar answered Sep 22 '22 21:09

deceleratedcaviar