Search code examples
c++templateslinkagevariable-templates

Why does const affect linkage of an instantiation of a global variable template in gcc?


I'm taking addresses of the following instantiated variable templates from two translation units:

template<class T> bool b = true;
template<class T> const bool cb = true;
template<class T> inline const bool icb = true;

I'm printing addresses of b<int>, cb<int> and icb<int>. Here is what clang says:

0x6030c0 0x401ae4 0x401ae5  // first translation unit
0x6030c0 0x401ae4 0x401ae5  // second translation unit

All addresses are the same, kind of expected. And here is what gcc says:

0x6015b0 0x400ef5 0x400ef4  // first translation unit
0x6015b0 0x400ef6 0x400ef4  // second translation unit

The address of cb<int> changes. Huh? Is this a bug? If not, could someone please explain this effect to me?


Solution

  • This, to me, appears to be related to CWG Issue 1713:

    Linkage of variable template specializations

    Given a namespace-scope declaration like

    template<typename T> T var = T();
    

    should T<const int> have internal linkage by virtue of its const-qualified type? Or should it inherit the linkage of the template?

    Notes from the February, 2014 meeting:

    CWG noted that linkage is by name, and a specialization of a variable template does not have a name separate from that of the variable template, thus the specialization will have the linkage of the template.

    Clang seems to be following it. The template name has external linkage, and so does the variable spun from it.

    Ultimately, the intended linkage of variable template specialization is not too well specified currently by the standard itself. It is specified for regular variables, but the templates are a different beast.