c++ - 不同模块中的结构定义不明确

标签 c++ visual-studio c++11 struct compiler-bug

我有一个带有 MS Visual Studio 2015 的大型 C++11 项目,它在两个模块(= 编译单元、cpp 文件)中定义了两个名称相同但内容不同的结构。由于结构仅在模块内定义和使用,而不是通过任何头文件导出以供共享使用,因此应该允许这样做,而且实际上编译器和链接器都不会报告任何错误或警告。但是在运行时,我从包含该结构的无序映射的构造函数中得到了访问冲突。 Visual Studio 2017 也会出现此问题,但 gcc5.4 不会。在我看来,这是一个编译器错误,但我不确定。 这里有一些最小化的源代码来重现问题,只需链接任何可执行文件即可在 main() 之前的启动期间获取访问冲突。

模块1.cpp:

#include <unordered_map>
struct AmbigousStruct {
    int i1;
    int i2;
    int i3;
};
static const std::unordered_map<int, AmbigousStruct>
s_ambigousStructMap{
    { 0, { 0, 1, 2 } }
};

模块2.cpp:

#include <unordered_map>
struct AmbigousStruct {
    int i1;
    int i2;
};
static const std::unordered_map<int, AmbigousStruct>
s_ambigousStructMap{
    { 0, { 0, 1 } }
};

问题似乎与在模板类(本例中为 unordered_map)中使用结构有关,因为它不会发生在结构的简单实例中,即 module2.cpp:

static const AmbigousStruct s_ambigousStructInstance{ 0, 1 };

最佳答案

您有两个具有外部链接的类类型,具有相同的名称,在不同的翻译单元中定义。他们的成员不匹配,这违反了单一定义规则。您的程序格式错误,无需诊断。

您需要对该结构定义强制进行内部链接。 C++ 标准允许您使用匿名命名空间来做到这一点。事实上,匿名 namespace 使其中的一切 都具有内部链接。所以你不需要 static 修饰符来做其他事情:

namespace {
  struct AmbigousStruct {
    int i1;
    int i2;
  };
  const std::unordered_map<int, AmbigousStruct>
  s_ambigousStructMap {
    { 0, { 0, 1 } }
  };
}

关于c++ - 不同模块中的结构定义不明确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46999413/

相关文章:

c++ - 显示器之间的Qt自定义无框窗口中的绘画问题

c++ - 静态库中的对象注册

git - 为什么我尝试使用 git 在 vs2013 中提交时得到 "Invalid path for filesystem"?

visual-studio - 使用 Resharper 时找不到元数据窗口 (F12)

c++ - 如何将解决方案从 Visual Studio 2010 降级到 Visual Studio 2005?

C++ condition_variable wait_for 立即返回

c++ - 不明白为什么我会收到错误消息

c++ - 错误:预期 ";"使用 std::vector<...>::const_iterator 无信息编译错误?

c++ - 如果 std::move 用作 && 参数的参数,它是否会调用复制运算符?

c++ - 设置差异的输出可以存储在第一个输入中吗?