c++ - 具有 T=<未命名命名空间类> 的函数模板特化的静态局部变量是否必须是唯一的?

标签 c++ templates static undefined-behavior icc

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

我将不胜感激。也许这毕竟是一个编译器错误,并且已经被报告过?

最佳答案

这对我来说像是一个错误。出租A1A 的实例之一和 A2成为另一个:

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

或者f<A1>f<A2>应该有不同的名称修改,这将导致 x 的两个版本有不同的名称修改(我认为一些编译器实际上生成一个随机值以使匿名 namespace 内的名称唯一),否则 x不应该有内部链接(因为本地类型用于实例化 f ,这应该使得不可能在另一个翻译单元中复制)。

关于c++ - 具有 T=<未命名命名空间类> 的函数模板特化的静态局部变量是否必须是唯一的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33262590/

相关文章:

javascript - JavaScript 中的公共(public)静态对象

c++ - 为什么 C++ 参数范围会影响命名空间内的函数查找?

c++ - initializer_list 和模板类型推导

C++ 命名空间和模板

ASP.NET 全局/静态存储?

c++ - 只有公共(public)静态方法的帮助类

javascript - IntelliJ 中的自定义关键字建议

c++ - 将 C++ 项目升级到 VS2015,但链接器仍在寻找 VC100 Boost 库

c++ - 继承的构造函数不能用于复制对象

c++ - 错误C++: ‘const_iterator’没有命名类型;