神秘链接器警告:两个模块中定义的公共符号

mar*_*rcp 3 c++ c++builder

我有2个字符串数组,在头文件中定义如下:

#ifndef DRC_DefinesH
#define DRC_DefinesH
#include <string>
#include <System.hpp>
//---------------------------------------------------------------------------

std::string MagFields[] = {
   "SCAN", "EVENT", "EVENT2", "EVENT1", "EVENT3", "VECTORX", "VECTORY", "VECTORZ", "MAG1RAW", "MAG2RAW", "MAG3RAW",
   "MAG4RAW", "MAG1UNCOMP", "MAG2UNCOMP", "MAG3UNCOMP", "MAG4UNCOMP", "MAG1COMP", "MAG2COMP", "MAG3COMP", "MAG4COMP",
   "GRAD1", "GRAD2", "GRAD3", "UTC", "LAT", "LON", "ALT", "ANALOG1", "ANALOG2", "ANALOG3", "ANALOG4", "SYSTIME"};

std::string AnalogFields[] = {
   "SCAN", "EVENT0", "EVENT1", "EVENT2", "EVENT3", "ANALOG1", "ANALOG2", "ANALOG3", "ANALOG4", "ANALOG5", "ANALOG6",
   "ANALOG7", "ANALOG8", "ANALOG9", "ANALOG10", "ANALOG11", "ANALOG12", "ANALOG13", "ANALOG14", "ANALOG15", "ANALOG16",
   "ANALOG17", "ANALOG18", "ANALOG19", "ANALOG20", "ANALOG21", "ANALOG22", "ANALOG23", "ANALOG24", "ANALOG25",
   "ANALOG26", "ANALOG27", "ANALOG28", "ANALOG29", "ANALOG30", "ANALOG31", "ANALOG32"};

... other stuff

    #endif
Run Code Online (Sandbox Code Playgroud)

此标头包含许多其他内容,并且间接包含在C++ Builder XE2项目的每个单元中.当我构建项目时,我得到很多链接器警告声明

"public symbol _MagFields and _AnalogFields are defined in both modules AAA and BBB"

其中AAA和BBB是项目中每个单元的组合.

这些特殊声明可以移动到单元的实现端,警告消失,但我想了解为什么有必要.Embarcadero文档告诉我如何摆脱警告,而不是它的含义.

Mik*_*our 7

您正在标题中定义数组,在包含标题的每个翻译单元中给出定义.但是你只允许一个单一的定义,因为定义是导致为数组分配内存的原因,它只能存在于一个地方.这被称为一个定义规则.

将定义移动到源文件中,因此它们不会重复.然后只需在头文件中声明数组:

extern std::string MagFields[];
extern std::string AnalogFields[];
Run Code Online (Sandbox Code Playgroud)

如果您不需要修改它们,另一个选项是声明它们const为它们提供内部链接,以便包含该定义的每个转换单元获得它自己的数组副本.这有一个缺点,你最终会在程序中使用多个阵列副本,浪费内存.

  • 包含防护措施可防止同一.cpp文件中的多个包含同一文件,但不会阻止不同的.cpp文件. (3认同)