[cfe-dev] Mangling & linkage of unnamed but instantiated nested classes

Richard Smith richard at metafoo.co.uk
Wed Oct 31 14:30:49 PDT 2012


On Wed, Oct 31, 2012 at 2:19 PM, Eli Friedman <eli.friedman at gmail.com> wrote:
> On Wed, Oct 31, 2012 at 12:37 PM, David Blaikie <dblaikie at gmail.com> wrote:
>> Hi John, (& cfe-dev)
>>
>> I mentioned this in person last week & wanted to provide you with some
>> more details & ask for your opinion.
>>
>> Backstory:
>>
>> I originally came across this while trying to use
>> -Wunused-member-function & found it was flagging code like this:
>>
>> struct foo {
>>   struct {
>>     void func() { ... } // warning that this is 'unused'
>>   } x;
>> };
>>
>> This surprised me, so I looked around & found that this function has
>> "no linkage". This seemed strange (because I would expect to be able
>> to call the function from multiple TUs that included the header
>> defining 'foo', compare its address for equality, & such things) & it
>> looks like the Right Thing is for func() to have the same linkage as,
>> say, an inline member function of 'foo' would have.
>>
>> The standard (3.5[basic.link]) seems to "miss" this case depending on
>> how you read it:
>>
>> 1) arguably p2, which says that "A name is said to have linkage when
>> it might denote the same ... function ... as a name introduced by a
>> declaration in another scope: - When a name has external linkage, the
>> entity it denotes can be referred to by names from scopes of other
>> translation units or from other scopes of the same translation unit"
>>
>> 2) p5: "... a member function ... has external linkage if the name of
>> the class has external linkage" (with an exception only for unnamed
>> classes (& enumerations) defined in class-scope typedef declarations
>> such that the class or enumeration has the dypedef name for linkage
>> purposes (7.1.3)) & there are no rules that seem to govern the linkage
>> of this unnamed class.
>>     p8 "Names not covered by these rules have no linkage"
>
> [basic.link]p8: "A type is said to have linkage if and only if [...]
> it is an unnamed class or enumeration member of a class with linkage".
>
> I'm going to assume it's an oversight in the standard that the members
> of such an unnamed class don't have linkage.

The rules also seem to miss anonymous classes declared within inline
functions, for which we also pick an incorrect mangled name and
linkage:

inline int f() {
  struct {
    int f() { return 0; }
  } s;
  return s.f();
}
int k = f();

Clang emits:

0000000000000000 t _ZZ1fvEN3$_01fEv

g++ emits:

0000000000000000 W _ZZ1fvENUt_1fEv



More information about the cfe-dev mailing list