Search code examples
c++language-lawyer

Why does specialization of a static variable template result in multiple definition error?


As seen in this answer, duplicated names in separate translation units do not violate ODR if they have internal linkage (declared static) because they actually refer to different entities. Furthermore, explicit specialization of a static template function also has internal linkage. However, as the below illustrates, this does not seem to be the case for specialization of variable templates.

g++ and clang++ agree on the code snippet below. The function specialization compiles but the variable specialization emits an error. Assuming the compilers are correct, why is the variable case different from the function case? A reference to the standard is appreciated.

Files a.cpp and b.cpp both contain

template <typename T> static void foo() {}
template <> void foo<int>() {} // ok

template <typename T> static void* ptr = nullptr;
template <> void* ptr<int> = nullptr; // error: multiple definition of `ptr<int>'

static int a = 0; // ok

Solution

  • The compilers are not behaving correctly. They should behave as you expect. The explicit specialization doesn't introduce a new name. The name still has the linkage given to it by the primary template, which is internal linkage.

    Therefore, the explicit specializations define different entities in the two translation units and the linker should have no reason to complain.

    I could find an old Clang bug report here. No luck finding one for GCC so far.