In the code bellow is listed example of forward declaration of constant template variables which compiles on both clang and 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>;
Nevertheless if I declare the variables non const, gcc produces a linker error:undefined reference to value4<int>
and undefined symbol value5<int>
, but clang accepts the code:
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
Initially I was confident all those uses cases where standard compliant. But because gcc produces a linker error for the last two cases, I was wondering if any of these forward declarations were legal? Is gcc wrong or am I on a no diagnostic required error? May a forward declaration followed by an inline definition of template variables as value3
or value5
in multiple translation unit cause odr violation?
Linking phase error demonstration
Note: In this answers to this questions it seems they have overlooked the possibility to declare the variable as an extern const.