On Wednesday, October 6, 2021 at 4:12:52 PM UTC-4, Tim Rentsch wrote:
> James Kuyper <
james...@alumni.caltech.edu> writes:
>
> > On 9/12/21 9:44 AM, Chris Vine wrote:
...
> >> For functions, it does more than affecting naming. The language
> >> linkage of a function determines two things: the function's name
> >> (name mangling) and the function's type (calling convention).
> >
> > Furthermore, and not widely appreciated, those two aspects are
> > separable by using a typedef for a function's type. The language
> > linkage of the typedef determines the calling convention, while the
> > language linkage of the function itself determines the name
> > mangling.
> Can you illustrate how that would be done? Since the language
> linkage of a function is part of its type, it sounds like trying
> to do such a thing would inevitably lead to undefined behavior.
The language linkage of a function's type is indeed part of that type. The
language linkage of a function's name is not. The standard's description of
language linkage in 9.11p1 starts with the sentence "All function types,
function names with external linkage, and variable names with external
linkage have a language linkage.", clearly making the point that the
language linkage of a function's type is a distinct thing from the language
linkage of a function's name. The standard could have inextricably linked
them together - but it does not. In fact, 9.11p5 includes an example
demonstrating how they can be separated:
extern "C" typedef void FUNC();
FUNC f2; // the name f2 has C ++ language linkage and the
// function’s type has C language linkage
Now, the standard can and does contain example code that violates a C++
rule, as a way of explaining what that rule means. However, when it does so,
it almost always includes a comment next to the offending line pointing out
that it violates a rule. There's no such comment in this example. In fact, the
only comments explicitly describe the well-defined meaning of that code.
All quotes are from n4860.pdf, the latest draft version of the C++ language
that I have access to. However, this is not a new feature of the language; it
has been part of standard C++ for as long as C++ has been standardized.
I'm not sure about pre-standard C++ - my copy of Stroustrup's book went
missing many years ago.
The C++ language linkage of f2's name means that it can be referred to by
name in C++ code, but not in C code. The C language linkage of f2's type
means that f2 can called from C as well as from C++. However, since the
function's name can't be referred to by C code, it must be called using a
pointer, and that pointer's value can only come from C++ code. It could be
passed to the C part of a program as a function parameter, or returned as
the value of a function call, or placed in a function pointer object shared
between the C and C++ parts of a program.
I don't see any reasonable use for the opposite: a function whose name has
C language linkage and whose type has C++ language linkage. C has no way
of correctly declaring the type of the function associated with that name,
and the function's name cannot be declared without specifying it's type.
Such a function would be callable by name from C++ but I don't see any
particular advantage of that.
I don't think that the ability to separate the language linkage of a function's
type from the language linkage of the function's name was a strongly desired
feature in itself. I suspect that it is simply a side-effect that arose naturally
from the fact that those are two different aspects of language linkage,
combined with the way typedefs work.