Lingxi
Lingxi

Reputation: 14977

When explicit template instantiation definition precedes explicit declaration, GCC and clang disagree

See the following code:

#include <vector>

template class std::vector<int>;
extern template class std::vector<int>;

int main() {}

While GCC 5.2 compiles fine, clang 3.6 gives the following error message:

main.cpp:4:28: error: explicit instantiation declaration (with 'extern') follows explicit instantiation definition (without 'extern')
extern template class std::vector<int>
                           ^
main.cpp:3:21: note: explicit instantiation definition is here
template class std::vector<int>
                    ^
1 error generated.

Still, for the following code

template <typename T>
void f() {}

template void f<int>();
extern template void f<int>();

int main() {}

Both GCC and clang errored out. The message for GCC is

main.cpp:5:29: error: duplicate explicit instantiation of 'void f() [with T = int]' [-fpermissive]
 extern template void f<int>();

and the one for clang is

main.cpp:5:22: error: explicit instantiation declaration (with 'extern') follows explicit instantiation definition (without 'extern')
extern template void f<int>();
                     ^
main.cpp:4:15: note: explicit instantiation definition is here
template void f<int>();
              ^
1 error generated.

What's going on with the two guys? Does the standard forbid an explicit template instantiation declaration to be preceded by an explicit definition? It makes little sense to me. After all, what harm could it be to define first and then declare? Just think about the case with non-template functions.

Upvotes: 1

Views: 813

Answers (1)

user657267
user657267

Reputation: 21000

From [temp.explicit] / 11

If an entity is the subject of both an explicit instantiation declaration and an explicit instantiation definition in the same translation unit, the definition shall follow the declaration.

GCC should be giving an error for the first example too.

Related bug from 2008, GCC seems to have problems detecting the error with classes, the following is also missed

template <typename T> class f {};

template class f<int>;
extern template class f<int>;

int main() {}

Upvotes: 2

Related Questions