Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

erroneous explicit template specialization of variable template in gcc

// i.h

template<int> extern int const i;

// i.cpp

#include "i.h"
template<> extern int constexpr i<0> = 42;

// main.cpp

#include "i.h"
int main()
{
  return i<0>;
}

In C++14/17 mode this returns 42 with clang, but is an error with gcc: "explicit template specialization cannot have a storage class".

Is this a bug in gcc?

like image 252
x y Avatar asked Oct 15 '17 07:10

x y


People also ask

What is explicit template specialization?

Explicit (full) specializationAllows customizing the template code for a given set of template arguments.

When we specialize a function template it is called?

To do so, we can use a function template specialization (sometimes called a full or explicit function template specialization) to create a specialized version of the print() function for type double.

What is the other name of full specialization?

Explanation: explicit specialization is another name of full specialization.


1 Answers

There is a rather simple solution to this whole issue. Please additionally see this post on the ISO C++ Standard - Discussion forum and the reply from Richard Smith.

1. extern must not be specified in an explicit specialization

So to answer the original question: no, it is not a bug in gcc, it is correct to report an error (as Massimiliano Janes already answered).

In contrast clang actually has a bug here (as Massimiliano Janes already guessed) because extern is accepted. Maybe clang accepts it silently because it is the same as that of the primary template.

2. Theoretically (according to the standard) the solution is to drop extern because with templates linkage is by name and so the specialization 'inherits' the linkage of the primary template (again see Massimiliano Janes' answer)

But in practice it does not work because both compilers are incorrect here and the explicit specialization incorrectly has internal linkage instead of the linkage of the primary template which is external.

3. In summary:

gcc never compiles which is correct in (1) but incorrect in (2). clang compiles in (1) which is incorrect but does not compile in (2) which is also incorrect.

I'll file a bug report for clang. If someone is interested please feel free to file a bug for gcc. I won't do this because (unfortunately) I can't use gcc in my development environment Visual Studio.

like image 101
x y Avatar answered Oct 07 '22 01:10

x y