C ++ Linker抱怨char *的多个定义,但不是std :: string

时间:2015-02-27 09:28:07

标签: c++ linker-errors

在一个大项目中,我有一个.h文件,它在命名空间中定义了很多常量。引入const char *常量导致链接器错误抱怨多个定义。

实施例H

#include <string>
namespace Dv
{
    const int MAX = 10;
    const std::string NAME = "bobo";

    const char* NAME2 = "fred";  // <-- ERROR: multiple definition of `Dv::NAME2'
}

exA.cpp

#include "ex.h"
void aFunction() { printf("this is aFunction\n"); }

exB.cpp

#include "ex.h"    
void aFunction(void);

int main(int argc, char **argv)
{
    aFunction();
    return 0;
}

编译和链接

g++ -c exA.cpp
g++ -c exB.cpp
g++ exA.o exB.o -o ex
exB.o:(.data+0x0): multiple definition of `Dv::NAME2'
exA.o:(.data+0x0): first defined here
collect2: ld returned 1 exit status

如果.h文件中包含NAME2,则会发生链接器错误。为什么呢?

如果MAX也是POD(如char []?),为什么链接器不会抱怨多个 int MAX 定义? (或者多个 std :: string NAME 定义?)

在这种情况下,我不明白char []的特殊之处。

由于

1 个答案:

答案 0 :(得分:2)

根据C ++标准(3.5程序和链接)

  

3具有命名空间范围(3.3.6)的名称具有内部链接(如果是)   

的名称      

- 一个非易失性变量,显式声明为const或constexpr,既未明确声明为extern,也未声明   宣布有外部联系;或

  

4直接或间接声明的未命名命名空间或命名空间   在未命名的命名空间内有内部链接。 所有其他   命名空间具有外部链接。具有命名空间范围的名称   没有给出上面的内部联系具有相同的联系   封闭命名空间,如果它是 - 变量的名称;或

在此命名空间定义

namespace Dv
{
    const int MAX = 10;
    const std::string NAME = "bobo";

    const char* NAME2 = "fred";  // <-- ERROR: multiple definition of `Dv::NAME2'
}

(唯一的)变量NAME2不是常量,因此具有外部链接。

您可以将其定义为内部链接,例如使用关键字static。例如

namespace Dv
{
    const int MAX = 10;
    const std::string NAME = "bobo";

    static const char* NAME2 = "fred";
}

或者可以将其定义为常量

namespace Dv
{
    const int MAX = 10;
    const std::string NAME = "bobo";

    const char * const NAME2 = "fred";
}