我们使用英特尔 C++ 编译器并检测到它错误编译(?)以下内容,减少了对 boost::function<Ponies()> f(unnamedNamespacedFunctor)
的使用.
a1.cc:
template<typename T>
int f(T) { static int x = T::x; return x; }
namespace { struct A { static const int x = 1; }; }
int f1() {
return f(A());
}
a2.cc:
template<typename T>
int f(T) { static int x = T::x; return x; }
namespace { struct A { static const int x = 0; }; }
int f2() {
return f(A());
}
主.cc:
#include <cstdio>
int f1();
int f2();
int main() {
std::printf("%d != %d\n", f1(), f2());
}
命令行:
# icpc a1.cc a2.cc main.cc -o main
# ./main
0 != 0
我的问题是:这是否合规?在此类实例化中使用静态局部变量是否会产生未定义的行为?在检查生成的符号时,我注意到虽然 f
是有本地链接,正如我所怀疑的那样,x
静态变量接收弱链接,因此两个 x
'es 被合并,它变成了被选择的彩票
# icpc a2.cc a1.cc main.cc -o main
# ./main
1 != 1
我将不胜感激。也许这毕竟是一个编译器错误,并且已经被报告过?
最佳答案
这对我来说像是一个错误。出租A1
是 A
的实例之一和 A2
成为另一个:
我假设静态 x
具有弱链接,因此链接器可以在相同实例化的多个拷贝之间合并静态拷贝。 (例如,如果您设法在两个不同的翻译单元中实例化 f<A1>
。)
或者f<A1>
和 f<A2>
应该有不同的名称修改,这将导致 x
的两个版本有不同的名称修改(我认为一些编译器实际上生成一个随机值以使匿名 namespace 内的名称唯一),否则 x
不应该有内部链接(因为本地类型用于实例化 f
,这应该使得不可能在另一个翻译单元中复制)。
关于c++ - 具有 T=<未命名命名空间类> 的函数模板特化的静态局部变量是否必须是唯一的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33262590/