我在Win32控制台应用程序中有2个文件,A.cpp和B.cpp.
这2个文件只包含以下2行代码:
#include "stdafx.h"
int k;
Run Code Online (Sandbox Code Playgroud)
编译时会产生错误
Error 1 error LNK2005: "int k" (?a@@3HA) already defined in A.obj
Run Code Online (Sandbox Code Playgroud)
我不明白发生了什么.
有人可以向我解释一下吗?
Alo*_*ave 94
为什么这个错误?
你打破了一个定义规则,从而打破了链接错误.
建议的解决方案:
如果在两个cpp文件中需要相同的命名变量,则需要使用Nameless命名空间(匿名命名空间)来避免错误.
namespace
{
int k;
}
Run Code Online (Sandbox Code Playgroud)
如果您需要跨多个文件共享相同的变量,则需要使用extern.
啊
extern int k;
Run Code Online (Sandbox Code Playgroud)
A.cpp
#include "A.h"
int k = 0;
Run Code Online (Sandbox Code Playgroud)
B.cpp
#include "A.h"
//Use `k` anywhere in the file
Run Code Online (Sandbox Code Playgroud)
Mic*_*ati 75
将/ FORCE:MULTIPLE添加到链接器命令行选项.
来自MSDN:"使用/ FORCE:MULTIPLE创建输出文件,无论LINK是否为符号找到多个定义."
Jer*_*fin 14
如果你想要引用同一个变量,那么其中一个应该有int k;,而另一个应该有extern int k;
对于这种情况,您通常将definition(int k;)放在一个.cpp文件中,并将声明(extern int k;)放在标题中,以便包含在您需要访问该变量的任何位置.
如果您希望每个k变量都恰好具有相同的名称,则可以将它们标记为static:( static int k;在所有文件中,或至少除一个文件外).或者,您可以使用匿名命名空间:
namespace {
int k;
};
Run Code Online (Sandbox Code Playgroud)
同样,除了最多一个文件之外.
在C中,编译器通常对此不太挑剔.具体来说,C有一个"暂定"的概念,所以如果你有int k;两次(在相同或不同的源文件中),每个都将被视为暂定,并且它们之间不会有冲突.但是,这可能有点令人困惑,因为您仍然不能有两个包含初始值设定项的定义 - 初始化程序的定义始终是完整定义,而不是暂定定义.换句话说,int k = 1;出现两次将是一个错误,但int k;在一个地方而int k = 1;在另一个地方则不会.在这种情况下,int k;将被视为暂定定义和int k = 1;定义(并且都指向相同的变量).
假设您希望'k'在不同的.cpp文件中是不同的值(因此将其声明两次),请尝试将两个文件更改为
namespace {
int k;
}
Run Code Online (Sandbox Code Playgroud)
这保证了名称"k"在翻译单元中唯一地标识"k".旧版本static int k;已弃用.
如果您希望它们指向相同的值,请将其更改为extern int k;.
两个文件都将变量定义k为整数(int).
结果,链接器看到两个具有相同名称的变量,并且不确定如果您引用它应该使用哪个变量k.
要解决此问题,请将其中一个声明更改为:
extern int k;
Run Code Online (Sandbox Code Playgroud)
这意味着:"k是一个整数,在这里声明,但在外部定义(即另一个文件)."
现在只有一个变量k,可以由两个不同的文件正确引用.