Bug in c++11 mode when instantiating template with local class

Edward Diener eldlistmailingz@tropicsoft.com
Wed Jun 28 15:00:00 GMT 2017


On 6/24/2017 7:01 AM, Jonathan Wakely wrote:
> On 23 June 2017 at 18:43, Edward Diener wrote:
>> On 6/23/2017 10:46 AM, Jonathan Wakely wrote:
>>> I don't think it's a bug. The code can be simplified considerably:
>>>
>>> template<void(*)()> struct helper { };
>>>
>>> struct AClass
>>> {
>>>     static void StaticFunction() { }
>>> };
>>>
>>> int main()
>>> {
>>>     struct ANestedClass
>>>     {
>>>       static void StaticFunction() { }
>>>     };
>>>
>>>     helper<&AClass::StaticFunction> ok;
>>>     helper<&ANestedClass::StaticFunction> error;
>>> }
>>>
>>> GCC, Clang and EDG all reject this for the same reason: you're using
>>> the address of a function with no linkage for a non-type template
>>> argument.
>>>
>>> [basic.link] says that although ANestedClass has internal linkage, the
>>> static member function has no linkage.
>>
>>
>> Could you point out where in [basic.link] this is specified ? I admit I have
>> a great deal of trouble understanding the rules for internal, external, and
>> no linkage of names in section 3.5 of the C++ standard. But I do find it odd
>> that if a local class name has internal linkage, a static member function
>> name of that local class has no linkage.
> 
> I misread it as saying ANestedClass has internal linkage, I think it
> also has no linkage (which would be why its member has no linkage).
> 
> Parargaph 8: "Names not covered by these rules have no linkage."

You are correct.

> 
> 
> 
> 
>>>
>>> N.B. https://wg21.link/n2187 allowed types with internal linkage to be
>>> used for template arguments, and https://wg21.link/cwg1155 allowed the
>>> addresses of objects with internal linkage to be used for non-type
>>> template arguments, but internal linkage is not the same as no
>>> linkage.
>>>
>>> I believe the reason the code is invalid is because otherwise you
>>> could declare an object with external linkage using a type with no
>>> linkage:
>>>
>>> static helper<&ANestedClass::StaticFunction> foo;
>>
>>
>> In your example doesn't 'foo' have internal linkage because it is declared
>> 'static' ?
> 
> No, that only applies to static variables at namespace-scope. Looking
> at it again, that name has no linkage either (it can't be referred to
> from other scopes). So I'm not sure of the reason for the rule against
> using types with no linkage as non-type template arguments.

I asked about this at
https://groups.google.com/a/isocpp.org/forum/#!forum/std-discussion
with the question
https://groups.google.com/a/isocpp.org/forum/#!topic/std-discussion/f4Tmi6vibuQ.
So far I have not received any answers. If you know of any other place 
where I might receive an explanation please say so. I understand that 
gcc is doing the correct thing, even if I do not understand the C++ 
standard reason for the rule.



More information about the Gcc-help mailing list