C++ 如何避免头文件中定义的变量出现 LNK2005 链接器错误?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5574499/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 18:26:15  来源:igfitidea点击:

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

c++headerincludelinker-errors

提问by Mark Lalor

I have 3 cpp files that look like this

我有 3 个看起来像这样的 cpp 文件

#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?

这是为什么?

回答by James Michael Hare

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:

请记住,#include 大致类似于将包含的文件剪切并粘贴到包含它的源文件中(这是一个粗略的类比,但您明白了)。这意味着如果你有:

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.

在头文件中,并且该头文件被程序中的三个源文件包含,那么它们都将定义一个名为 x 的全局变量,该全局变量会发生冲突。

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.

您想要做的是将变量定义为 extern 以便 .cpp 文件都将获得声明,然后在您的 .cpp 文件之一中给出实际定义。

in Variables.h:

在 Variables.h 中:

extern int x;

in SomeSourceFile.cpp

在 SomeSourceFile.cpp 中

int x;

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

当然,我建议不要使用全局变量,但如果您必须使用它们,这将防止它们发生冲突。

回答by deceleratedcaviar

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

因为“int滑块”已经在另一个文件中定义了?检查您是否有头球后卫...

#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.

如果您确实希望它们是全球性的,请查看 James 的解决方案。

回答by Greg Hewgill

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

这是因为编译器分别编译每个.cpp文件,.obj为每个文件创建一个文件。您的标题似乎有以下内容:

int slider;

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

当这包含在三个.cpp文件中的每个文件中时,您将获得该变量的三个副本int slider,就好像您已在每个.cpp文件中声明它一样。链接器抱怨这个是因为你没有三个同名的不同东西。

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

您可能想要做的是将头文件更改为:

extern int slider;

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

这告诉编译器slider某处有一个变量,但可能不是这里,并让链接器找出来。然后,在一个.cpp文件中:

int slider;

gives the linker one actual variable to link.

给链接器一个要链接的实际变量。

回答by Jess

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.

正在发生的事情是 Variables.h 中的每个变量都被赋予了每个单独的 c 文件的全局范围。当链接器编译所有 c 文件时,它会看到多个具有相同名称的变量。

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.

如果您想使用头文件中的变量作为全局变量,那么您必须在所有这些变量前面使用关键字“extern”,并且在主文件中不要使用关键字 extern。

main c:

主 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.

您可以创建两个文件 Variables.h 和 EVariables.h,或者只在 main.cpp 文件中声明变量。

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

一个更好的方法是创建一个 Variables 类并将引用传递给该类。

回答by Esaith

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.

我知道这是一个旧线程,但我是在 Google 的第一个搜索结果中发现它的。我通过放置变量静态解决了这个问题。

namespace Vert
{
   static int i;
}

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

我尝试了 extern 并且在我的情况下似乎没有解决问题。

回答by CarpeDiemKopi

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

尽管我使用外部定义,但我也遇到了这个错误。问题也在于初始化 extern 定义中的变量:

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

=> 没有错误,问题解决了

回答by Ali Awarke

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

如果通过“Variables.h”多次包含的变量被声明为const,也可以避免这种链接错误。