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

C++ Linker complains multiple definition of char* but not std::string

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

ex.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;
}

编译并Link

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[]在这种情况下有什么特别之处。

谢谢

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

3 A name having namespace scope (3.3.6) has internal linkage if it is the name of

— a non-volatile variable that is explicitly declared const or constexpr and neither explicitly declared extern nor previously declared to have external linkage; or

4 An unnamed namespace or a namespace declared directly or indirectly within an unnamed namespace has internal linkage. All other namespaces have external linkage. A name having namespace scope that has not been given internal linkage above has the same linkage as the enclosing namespace if it is the name of — a variable; or

在此命名空间定义中

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";
}