2

Function templates are not allowed to have C language linkage:

extern "C" {
    template<typename T>   // error: template with C linkage
    void bad_f() {}
}

This is reasonable, as there are potentially multiple instantiations, but, without name mangling, only one symbol that can be exported at the binary level.

However both GCC and Clang accept function templates with non-template C language linkage type:

extern "C" {
    using F = void();
}

template<typename T>
F f;

template<typename T>
void f() {}

This is surprising to me. It seems reasonable to assume that, analogously to non-template case, instantiations of f have names with C++ language linkage (i.e. name mangling happens) and types with C language linkage (i.e. C calling convention is used to call them).

Is f declaration actually well-formed C++? If so, does it do what I assume it does?

7
  • I don't get the question. Types and type aliases do not produce a linkage names/symbols. Commented 9 hours ago
  • @3CEZVQ I never said they do? Commented 9 hours ago
  • f is a variable, and as such isn't used for name-mangling. The symbol f will always have the name f, no matter its type. Commented 9 hours ago
  • 1
    @Someprogrammerdude F is a function type, F f; declares the function (template) f. Commented 9 hours ago
  • 1
    @Someprogrammerdude the type alias itself doesn't have language linkage, but the type it refers to does when it's a function type. Function types aliased under extern "C" have C language linkage. See dcl.link. Commented 6 hours ago

1 Answer 1

4

This is CWG1463. The restriction in question doesn't make a lot of sense for several reasons:

  1. language linkage is described as being a property of functions and variables whose names have external linkage (which for extern "C" is name mangling) and of function types (which is calling convention), and a function template is neither of those things ([temp.pre]/6 notwithstanding)
  2. we can't possibly want to give each specialization of a function template (which is not a function whose name has external linkage anyway) C language linkage because (as mentioned) there is only one unmangled name
  3. alias templates could benefit from "having" C language linkage for the function types in their definition and do not have any other potential meaning for it

Your declaration of f is almost an example of the last point: it can very well be useful to use a template to manufacture C-compatible functions (used by function pointers in C), but the trick of declaring one with a type alias works only in the special case that the function type is not dependent.

As such, we have (finally) written a paper (link live in December) that has been approved (but not yet applied) as a Defect Report: it removes the questionable rule entirely, letting the function types in template declarations have C language linkage, as well as formally prohibiting

template<class> extern "C++" void f();

(which implementations have always rejected) so that we can one day specify that that syntax overrides the function-type language linkage implied by an enclosing, say, extern "Java" if such ever becomes widespread.

Sign up to request clarification or add additional context in comments.

1 Comment

Oh, this is great, thank you for your work.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.