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

标签 c++ namespaces constants linker-errors linkage

在一个大项目中,我有一个 .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;
}

编译和链接

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

关于C++ 链接器提示 char* 的多个定义,但不是 std::string,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28761549/

相关文章:

c++ - 从 C++ 中的 .obj 文件中读取整数

c++ - 如何在堆上使用 vector 分配矩阵

kubernetes - kubernetes 命名空间中部署定义的唯一性

c++ - 嵌套与全局上下文中同级命名空间之间的区别

ruby - Ruby 中的动态常量分配

c++ - 如何计算对此函数的递归调用以及正确的答案是什么?

c++ - 如何使 C++ 中的 getopt 严格执行选项检查?

php - 如何在一个文件 yii2 中使用两个命名空间?

c++ - 为什么 "const T*"在 "void*"中被简单地转换为 "operator delete"?

algorithm - 如何在 sas 中计算 π?