How can I avoid the LNK2005 linker error for varia

2020-02-12 07:15发布

问题:

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?

回答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.



回答2:

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.



回答3:

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.



回答4:

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.



回答5:

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.



回答6:

This linking error can also be avoided if the variables included multiple times via the "Variables.h" are declared as const.



回答7:

I had this error too although I work with extern definitions. The problem was initializing the variables in the extern definitions too:

ID3D11VertexShader*         g_pVertexShader = nullptr;
...
extern ID3D11VertexShader*  g_pVertexShader = nullptr;  // here's the problem 

=> error

ID3D11VertexShader*         g_pVertexShader = nullptr;
...
extern ID3D11VertexShader*  g_pVertexShader;           // without initializing  

=> no error, problem solved