我正在为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:
另外,成员函数,静态数据成员,[...] 具有用于链接目的的typedef名称(7.1.3),如果类的名称具有外部,则具有外部链接 键。
但它们打破了N3376 [basic.link] p10的要求:
在对类型进行所有调整(其中typedefs(7.1.3)被其定义替换之后),类型 由引用给定变量或函数的所有声明指定的内容应相同[...]违反此规则的类型标识不需要诊断。
要100%确定这一点,需要对这些“类型的所有调整”进行定义,但在C ++ 11标准中似乎无处可寻。有没有,上面的推理是正确的吗?
答案 0 :(得分:3)
这是ODR违规行为。 Foo类型在每个文件中都有不同的声明。
一个定义说x是用外部链接声明的(可以是任何东西,在链接时确定),另一个定义是它是一个值为2的编译时常量。