在下面的代码中列出了常量模板变量的前向声明示例,它们在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错误还是我没有诊断要求错误?可以在多个翻译单元中将前缀声明后跟模板变量的内联定义作为 value3
或 value5
导致odr违规吗?
Linking phase error demonstration
注意:在这个问题的答案中,似乎他们忽略了将变量声明为extern const的可能性 .