c – 函数模板特化的静态局部变量是否必须是唯一的?

我们使用英特尔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

我很感激你的帮助.也许这实际上是一个编译器错误,它已经被报道了?

我假设静态x具有弱链接,因此链接器可以在同一实例化的多个副本之间合并静态副本. (例如,如果您设法在两个不同的翻译单元中实例化f<A1&gt ;.) f<A1>和f<A2>应该有不同的名称修改,这将导致x的两个版本具有不同的名称修改(我认为一些编译器实际上生成一个随机值,使匿名名称空间内的名称唯一),否则x不应该有内部链接(因为本地type用于实例化f,这使得它无法在另一个翻译单元中复制).

翻译自:https://stackoverflow.com/questions/33262590/are-static-locals-of-function-template-specializations-with-t-unnamed-namespace