具有 T=<unnamed namespaced class> 的函数模板专用化的静态局部变量是否需要是唯一的?

Are static locals of function template specializations with T=<unnamed namespaced class> required to be unique?

本文关键字:是否 静态 局部变量 唯一 函数模板 unnamed lt namespaced class 具有 gt      更新时间:2023-10-16

我们使用Intel 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 != %dn", 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
我很感激你的帮助。也许这实际上是一个编译器错误,它已经被报告了?

我觉得这像是一个bug。让A1A的实例化之一,A2为另一个实例化:

我假设静态x具有弱链接,以便链接器可以在相同实例化的多个副本之间合并静态副本。(例如,如果您设法在两个不同的翻译单元中实例化f<A1>。)

f<A1>f<A2>应该有不同的名称混淆,这将导致x的两个版本有不同的名称混淆(我认为一些编译器实际上生成一个随机值,使匿名命名空间内的名称唯一),或者x不应该有内部链接(因为一个本地类型被用来实例化f,这应该使它不可能复制在另一个翻译单元)。