具有 T=<unnamed namespaced class> 的函数模板特化的静态局部变量是否必须是唯一的?
Are static locals of function template specializations with T=<unnamed namespaced class> required to be unique?
我们使用英特尔 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());
}
main.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
被合并并且它成为被选中的彩票
# icpc a2.cc a1.cc main.cc -o main
# ./main
1 != 1
我将不胜感激。也许这毕竟是一个编译器错误并且已经被报告过?
我觉得这像是一个错误。让 A1
成为 A
的实例化之一,让 A2
成为另一个:
我假设静态 x
具有弱链接,以便链接器可以在 same 实例化的多个副本之间合并静态的副本。 (例如,如果您设法在两个不同的翻译单元中实例化 f<A1>
。)
f<A1>
和 f<A2>
应该有不同的名字修饰,这会导致 x
的两个版本有不同的名字修饰(我认为有些编译器实际上生成了一个随机值使匿名名称空间内的名称唯一),否则 x
不应具有内部链接(因为本地类型用于实例化 f
,这应该使其无法在另一个翻译单元中复制)。
我们使用英特尔 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());
}
main.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
被合并并且它成为被选中的彩票
# icpc a2.cc a1.cc main.cc -o main
# ./main
1 != 1
我将不胜感激。也许这毕竟是一个编译器错误并且已经被报告过?
我觉得这像是一个错误。让 A1
成为 A
的实例化之一,让 A2
成为另一个:
我假设静态 x
具有弱链接,以便链接器可以在 same 实例化的多个副本之间合并静态的副本。 (例如,如果您设法在两个不同的翻译单元中实例化 f<A1>
。)
f<A1>
和 f<A2>
应该有不同的名字修饰,这会导致 x
的两个版本有不同的名字修饰(我认为有些编译器实际上生成了一个随机值使匿名名称空间内的名称唯一),否则 x
不应具有内部链接(因为本地类型用于实例化 f
,这应该使其无法在另一个翻译单元中复制)。