Jam*_*mes 5 c++ gcc standards-compliance visual-c++
详细解释如下,问题在底部。
我的问题特别指的是在此处找到的当前 C++ 草案标准(以及当前的“主要”标准)。更具体地说,第 3.2 节第 6 点(第 35 页)指出each de?nition of D shall consist of the same sequence of tokens,关于成员函数和 ODR。
最近在一个项目中添加新的数据分析时遇到了如下问题。
我正在写一个文件,A.cpp。我创建了一个小的虚拟结构来保存一些数据。在这个例子中,我将称之为Data。
namespace Example {
struct Data {
//etc
};
//Use Data
};
Run Code Online (Sandbox Code Playgroud)
但是在另一个文件 B.cpp 中,命名空间Data内已经有一个结构体被调用Example。编译器Data::~Data();为这两个类生成,依次调用它们各自成员的析构函数。B.cpp 中的定义包含一个向量,当Data使用 A.cpp 中定义的布局在结构上调用时,该向量被破坏时会导致爆炸。虽然这两个结构似乎都能正常工作,没有编译时错误,但链接器似乎在链接时会选择一个定义并使用它,而忽略另一个定义。(因此Data在 A.cpp 内部的对象上引起爆炸)
在 GCC 或 MSVC 下不会发出警告。启用优化后,问题不会发生(函数是内联的,没有链接时间混淆)。
我的问题是,标准只说明行为是 undefined If D is a template and is de?ned in more than one translation unit。要么是我误解了标准,允许未定义的行为默默发生;或者 GCC 和 MSVC 都在默默地接受他们不应该接受的东西(并且应该拒绝产生输出或发出警告)(当前情况是未定义和不一致的行为,没有诊断)。
有人可以帮助我理解这与类中未定义的函数的冲突定义有何不同(这会导致警告/错误)。
\n\n有人可以帮助我理解这与类中未定义的函数的冲突定义有何不同(这确实会导致警告/错误)。
\n
不同之处在于,类内的函数定义名义上是隐式inline 的,这会在再次遇到该函数时禁止编译器发出警告。这并不意味着编译器必须内联它们 - 它可能决定使用任何启发式方法不打扰,或者它可能简单地在某些优化级别上从不内联。无论如何,如果您链接的代码看到了名义上内联非成员函数的不同定义,那么您就会遇到完全相同的问题。
\n见3.2/6
\n\n\n程序中可以有多个类类型的定义...只要每个定义出现在不同的翻译单元中,并且定义满足以下要求。
\n\xe2\x80\x94 D 的每个定义应由相同的标记序列组成;和
\n【其他要求】
\n
更一般地说,您应该将代码放入匿名名称空间中......它们旨在防止此类交叉翻译单元问题。
\n