为什么此模板变量会导致编译器警告?

时间:2014-06-28 07:38:14

标签: c++ templates clang compiler-warnings c++14

为什么我会从Clang那里得到这个警告?这似乎是对我的模仿常数的合理使用。

warning: variable 'M_PI<int>' has internal linkage but is not defined [-Wundefined-internal]

#include <iostream>

template <typename T>
constexpr T M_PI = T(3.1415926535897932);

template <typename T>
constexpr T CalcCircumference(T d)
{
    return d * M_PI<T>;
}

int main()
{
    std::cout << CalcCircumference(42.0f);
}

编辑:显然,一个简约的测试案例让一些人感到困惑。我已经点缀了一下,希望能够减轻它。

2 个答案:

答案 0 :(得分:3)

我认为你应该忽略警告,现在应该完全避免变量模板。

考虑

template <typename T> T var = 0;
int main() { return var<int>; }

编译时没有警告,链接和运行返回零。

template <typename T> T var = 0;
template <typename T> T func() { return var<T>; }
int main() { return func<int>(); }

此编译没有警告,但没有链接:它给出了错误消息。

$ clang++ test2.cc -o test2 -std=c++1y -pedantic -Wall
/tmp/test2-736968.o:test2.cc:function int func(): error: undefined reference to 'var'
clang: error: linker command failed with exit code 1 (use -v to see invocation)

强制显式实例化确实有效:

template <typename T> T var = 0;
template int var<int>;
template <typename T> T func() { return var<T>; }
int main() { return func<int>(); }

我会说这表明clang中变量模板的实现是不完整的。您对constexpr的使用仅仅是为了让clang检测到自己的不完整实现。

答案 1 :(得分:1)

这是早期版本的Clang中的一个错误(以PR19305提交)。另请参阅PR19571PR17846,它们是具有相似症状的不同错误。这些都在Clang 3.5中修复。