在下面的代码中列出了常量模板变量的前向声明示例,它们在clang和gcc上进行编译:

template<class T>
extern const T value;
template<class T>
const T value= 0;

auto test = value<int>;

template<class T>
extern const T value2;
template<class T>
constexpr T value2 =0;

auto test2 = value2<int>;

template<class T>
extern const T value3;
template<class T>
inline constexpr T value3 =0;

auto test3 = value3<int>;

然而,如果我声明变量非const,gcc会产生一个链接器错误: undefined reference to value4<int>undefined symbol value5<int> ,但clang接受代码:

template<class T>
extern T value4;
template<class T>
T value4= 0;

auto test4 = value4<int>; //gcc linker error

template<class T>
extern T value5;
template<class T>
inline T value5=0;

auto test5 = value5<int>; //gcc linker error

最初,我确信所有那些符合标准的用例 . 但是因为gcc在最后两个案例中产生了一个链接器错误,我想知道这些前向声明是否合法?是gcc错误还是我没有诊断要求错误?可以在多个翻译单元中将前缀声明后跟模板变量的内联定义作为 value3value5 导致odr违规吗?

Linking phase error demonstration


注意:在这个问题的答案中,似乎他们忽略了将变量声明为extern const的可能性 .