我正在为 C++11 开发静态分析器。类的静态 const 成员和链接之间存在交互,我不确定它是否已定义。仅当未定义此构造时,我的静态分析器才会发出警告。
例子是这个:
在文件 f1.cpp 中:
struct Foo {
static const int x = 2;
};
int main(void) {
return *&Foo::x;
}
在文件 f2.cpp 中:
struct Foo {
static int x;
};
int Foo::x;
使用 clang++ -std=c++11 -Weverything f1.cpp f2.cpp
编译和链接的两个文件不会引起警告并生成返回 0 的二进制文件。使用编译时的相同文件g++ -std=c++11 -Wall -Wextra -pedantic f1.cpp f2.cpp
没有警告并返回 2。
我的直觉是这个程序定义错误但不需要警告,因为:
两个名称 Foo::x 在 N3376[basic.link]p5 之后都有外部链接:
In addition, a member function, static data member,[...] has the typedef name for linkage purposes (7.1.3), has external linkage if the name of the class has external linkage.
但他们违反了 N3376[basic.link]p10 要求:
After all adjustments of types (during which typedefs (7.1.3) are replaced by their definitions), the types specified by all declarations referring to a given variable or function shall be identical [...] A violation of this rule on type identity does not require a diagnostic.
要 100% 确定这一点,需要为这些“所有类型调整”定义,但似乎在 C++11 标准中找不到。有没有,上面的推理是否正确?
最佳答案
这是 ODR 违规。 Foo 类型在每个文件中都有不同的声明。
一个定义说 x 是用外部链接声明的(可以是任何东西,在链接时确定),另一个定义是它是一个值为 2 的编译时常量。
关于c++ - 在另一个文件中定义的静态常量数据成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42555541/