This is a follow-up question to an answer to Is it possible to typedef a pointer-to-extern-“C”-function type within a template?
This code fails to compile with g++
, Visual C/C++, and Comeau C/C++ with basically the same error message:
#include <cstdlib>
extern "C" {
static int do_stuff(int) {
return 3;
}
template <typename return_t_, typename arg1_t_>
struct test {
static void foo(return_t_ (*)(arg1_t_)) { }
};
}
int main()
{
test<int, int>::foo(&do_stuff);
return EXIT_SUCCESS;
}
g++ says "error: template with C linkage", Visual C/C++ emits compiler error C2894, and Comeau C/C++ says "error: this declaration may not have extern "C" linkage".
The thing is, all are happy with:
#include <cstdlib>
extern "C" {
static int do_stuff(int) {
return 3;
}
struct test {
static void foo(int (*)(int)) { }
};
}
int main()
{
test::foo(&do_stuff);
return EXIT_SUCCESS;
}
Section 7.5, Linkage specifications, of the C++ Standard states:
A C language linkage is ignored for the names of class members and the member function type of class member functions.
And it even gives the example:
extern "C" {
class X {
void mf(); // the name of the function mf and the member
// function's type have C++ language linkage
void mf2(void(*)()); // the name of the function mf2 has C++ language
// linkage; the parameter has type pointer to C function
};
}
If templates were allowed in extern "C" blocks, then the member functions of the instantiations would have C++ linkage.
Why, then, does chapter 14, Templates, of the C++98 Standard state:
A template name may have linkage (3.5). A template, a template explicit specialization (14.7.3), and a class template partial specialization shall not have C linkage.
What does it mean that a template "may" have linkage? What is template linkage?
Why is it explicitly forbidden to have a template with C linkage, when a class is okay, and all member functions of instantiations of the template (the default constructor, destructor, and assignment operator overload) would have C++ linkage?
See Question&Answers more detail:os