【发布时间】:2017-03-02 12:27:49
【问题描述】:
我正在为 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 标准中似乎无处可寻。有没有,上面的推理正确吗?
【问题讨论】:
-
见§basic.def.odr/p5 特别是5.1:
There can be more than one definition of a class type...each definition of D shall consist of the same sequence of tokens; and
标签: c++ c++11 language-lawyer