我正在尝试尝试刷新的旧版C ++代码。
以前处理代码的承包商非常草率,不费心为某些类创建头文件,而是将所有内容转储到.cpp
,大量全局变量,7000以上的超大.cpp
文件中代码行。目前,我正在尝试将代码分成.h
和.cpp
个文件。
现有代码有效(在生产环境中编译并运行)。我使用了部分实用程序代码和一些变量,并将它们移至CASupporting.h
。编译了项目,并在Visual Studio中出现以下错误:
LNK1169 one or more multiply defined symbols found
Error LNK2005 "int * CAValidation::__invReasonCounts" (?__invReasonCounts@CAValidation@@3PAHA) already defined in AddressValidatorLib.obj
Error LNK2005 "int * CAValidation::__invReasonCounts" (?__invReasonCounts@CAValidation@@3PAHA) already defined in AddressValidatorLib.obj
问题变量为
//CASupporting.h
namespace CAValidation {
...
int __invReasonCounts[7] = { 0 };
...
}
我进行了全局搜索以查找__invReasonCounts
的其他定义,但结果为空。因此,我怀疑这与#include "CASupporting.h"
的使用方式有关。
当前包含的链看起来像:CASupporting.h
-> CAImpl.h
-> CAImpl.cpp
&CAValidator.h
(2个文件)。
CAValidator.h
-> CAValidator.cpp
出于好奇,我将int __invReasonCounts[7] = { 0 };
从CASupporting.h
移到了正在使用namespace CAValidation
的“ CAImpl.cpp”中的__invReasonCounts
中。项目编译没有错误。
答案 0 :(得分:3)
是的,如果您在标头中定义了(非内联)全局变量,并且标头包含在多个.cpp文件中,则由于违反ODR,您将出现链接器错误。
旧版C ++中最常见的修复方法是将定义移到.cpp文件中,并在.h文件中保留声明:
在.h中:
extern int __invReasonCounts[7];
在.cpp中:
int __invReasonCounts[7] = {0}; // compile-time initialization, safe
此外,请记住,以__
开头的符号(两个undescore)保留用于实现,不能在程序代码中使用。