2012-04-06 146 views
51

在Win32控制台应用程序中,我有2个文件,A.cpp和B.cpp。错误LNK2005,已定义?

两个2个文件只包含以下两行代码:

#include "stdafx.h" 
int k; 

当编译它产生的错误

Error 1 error LNK2005: "int k" ([email protected]@3HA) already defined in A.obj 

我不明白发生了什么。

有人可以向我解释这个吗?

+7

?那是你公司的名字吗?当您提出基本问题时,我不会建议签署公司名称。特别是如果你的客户希望你保护他们的某种信息。 – CodyBugstein 2014-01-26 13:45:42

+1

**提示fellas:**缺少'#include“stdafx.h”'也是此错误的来源。 – Bitterblue 2014-05-19 10:24:35

回答

77

为什么会出现此错误?

您打破了one definition rule因此链接错误。

建议的解决方法:


如果您需要在这两个cpp文件,然后你需要使用无名的命名空间(匿名命名空间),以避免错误的同名变量。

namespace 
{ 
    int k; 
} 

如果您需要共享在多个文件相同的变量,那么你需要使用extern

A.H

extern int k; 

A.cpp

#include "A.h" 
int k = 0; 

B.cpp

#include "A.h" 

//Use `k` anywhere in the file 
+2

如果使用'extern',则应在任何源文件中定义'k'一次。 – Mahesh 2012-04-06 16:57:34

+1

@Mahesh:但当然:) – 2012-04-06 16:58:53

+0

我也有这个问题,但我没有重新定义它,我试图用我的.dll在另一个.dll项目中为它做一个托管包装。有什么建议? – 2014-04-25 16:51:39

6

假设你想 'K' 是一个不同在不同的.cpp文件(因此宣布两次),尝试这两个文件更改为

namespace { 
    int k; 
} 

这保证了名为“K”唯一标识跨翻译单元“K” ENT值。旧版本static int k;已弃用。

如果您希望它们指向相同的值,请将其更改为extern int k;

1

如果您希望这些翻译单元共享此变量,请在A.cpp中定义int k;,并在B.cpp中放入extern int k;

13

如果你想同时引用相同的变量,其中一人应该有int k;,而其它的有extern int k;

对于这种情况,你通常把定义(int k;)在一个.cpp文件,并把头文件中的声明(extern int k;)将包含在需要访问该变量的任何位置。

如果希望每个k成为一个独立的变量,只是碰巧有相同的名称,你可以将它们标记为static,如:static int k;(中的所有文件,或者只有一个文件,至少所有)。或者,您可以使用匿名命名空间:

namespace { 
    int k; 
}; 

再次,除了最多只有一个文件。

在C中,编译器通常不太挑剔。具体来说,C有一个“暂定义”的概念,所以如果你有两次这样的东西(在相同或者不同的源文件中),每个都将被视为一个试探性的定义,并且它们之间不会有冲突。然而,这可能有点令人困惑,因为你仍然不能有两个包含初始化符的定义 - 带有初始化符的定义总是一个完整的定义,而不是一个试探性的定义。换句话说,int k = 1;出现两次将是一个错误,但int k;在一个地方和int k = 1;在另一个不会。在这种情况下,int k;将被视为暂定义,int k = 1;作为定义(并且都指向相同的变量)。

+0

+1但是杰里,如果你想添加一些关于C的话,那将是很好的。我想也许OP是来自C,它的“暂定”声明...... C/C++的差异让我困惑了一段日志时间。 – 2012-04-06 16:56:48

+0

当我仅定义一次变量时,static关键字帮助了我。谢谢! – Pete 2014-12-03 06:37:02

5

这两个文件都将变量k定义为整数(int)。

因此,链接器会看到具有相同名称的两个变量,并且如果您提到k,则不确定它应该使用哪一个。

为了解决这个问题,修改声明一个到:

extern int k; 

这意味着:“(即,其他文件)k为整数,这里声明,但限定在外部”。

现在只有一个变量k,可以由两个不同的文件适当引用。

+0

你能否在多个其他地方引用变量(即没有'extern')? – CodyBugstein 2014-01-26 13:52:18

1

链接器告诉你,你有多次定义的变量k。事实上,你在A.cpp和B.cpp中有一个定义。两个编译单元都会生成一个链接器用来创建程序的相应对象文件。问题是,在你的情况下,链接器不知道要使用的k的定义。在C++中,你可以只有一个定义相同的结构(变量,类型,函数)。

要解决它,你将不得不决定你的目标是什么

  • 如果你想有两个变量,并重命名k,您可以都使用匿名的命名空间。cpp文件,则请参考k,因为您现在正在执行此操作:

namespace { 
    int k; 
} 
  • 可以重命名k S的一个别的东西,从而避免重复确定指标。
  • 如果您只想定义k并在两个.cpp文件中使用该定义,则需要在extern int k;中声明一个,并将其保留为另一个。这将告诉链接器在这两种情况下使用一个定义(不变的版本) - extern意味着该变量是在另一个编译单元中定义的。
57

向链接器命令行选项添加/ FORCE:MULTIPLE。

MSDN:“使用/ FORCE:MULTIPLE创建输出文件,无论LINK是否找到符号的多个定义。” T&T Group?

+4

这是** only **解决方案,当链接器或预处理器无法看到该事物只定义**一次**!必须也是VS中的一些错误。我只是想知道为什么这么多人工作了这么久。 (我不是指这里的Q,而是我的链接器错误,这是来自空间的空间,我猜...) – Bitterblue 2014-05-19 09:58:21

+3

我有一种感觉,这是一种'蛮力'的做法,并不实际解决原来的问题;它使我的一半功能指向空值。由于这解决了我的问题,我给了这个答案+1。 – cybermonkey 2014-11-08 18:37:03

+1

想要指出的是,如果您正在使用新编译器编译使用旧编译静态库的代码库,则这可能是解决此问题的唯一方法。 – Predelnik 2015-03-19 19:17:05

相关问题