This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 113d. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2024-03-20


1603. Errors resulting from giving unnamed namespaces internal linkage

Section: 6.6  [basic.link]     Status: CD4     Submitter: Richard Smith     Date: 2013-01-09

[Moved to DR at the November, 2014 meeting.]

In C++03, all namespace-scope names had external linkage unless explicitly declared otherwise (via static, const, or as a member of an anonymous union). C++11 now specifies that members of an unnamed namespace have internal linkage (see issue 1113). This change invalidated a number of assumptions scattered throughout the Standard that need to be adjusted:

  1. 6.6 [basic.link] paragraph 5 says,

  2. a member function, static data member, a named class or enumeration of class scope, or an unnamed class or enumeration defined in a class-scope typedef declaration such that the class or enumeration has the typedef name for linkage purposes (9.2.4 [dcl.typedef]), has external linkage if the name of the class has external linkage.

    There is no specification for the linkage of such members of a class with internal linkage. Formally, at least, that leads to the statement in paragraph 8 that such members have no linkage. This omission also contradicts the note in 11.4.2 [class.mfct] paragraph 3:

    [Note: Member functions of a class in namespace scope have external linkage. Member functions of a local class (11.6 [class.local]) have no linkage. See 6.6 [basic.link]. —end note]

    as well as the statement in 11.4.9.3 [class.static.data] paragraph 5,

    Static data members of a class in namespace scope have external linkage (6.6 [basic.link]).
  3. The footnote in 6.6 [basic.link] paragraph 8 says,

  4. A class template always has external linkage, and the requirements of 13.4.2 [temp.arg.type] and 13.4.3 [temp.arg.nontype] ensure that the template arguments will also have appropriate linkage.

    This is incorrect, since templates in unnamed namespaces now have internal linkage and template arguments are no longer required to have external linkage.

  5. The statement in 9.2.2 [dcl.stc] paragraph 7 is now false:

  6. A name declared in a namespace scope without a storage-class-specifier has external linkage unless it has internal linkage because of a previous declaration and provided it is not declared const.
  7. The entire treatment of unique in 9.8.2.2 [namespace.unnamed] is no longer necessary, and the footnote is incorrect:

  8. Although entities in an unnamed namespace might have external linkage, they are effectively qualified by a name unique to their translation unit and therefore can never be seen from any other translation unit.

    Names in unnamed namespaces never have external linkage.

  9. According to 11.8.4 [class.friend] paragraph 4,

  10. A function first declared in a friend declaration has external linkage (6.6 [basic.link]).

    This presumably is incorrect for a class that is a member of an unnamed namespace.

  11. According to Clause 13 [temp] paragraph 4,

  12. A non-member function template can have internal linkage; any other template name shall have external linkage.

    Taken literally, this would mean that a template could not be a member of an unnamed namespace.

Proposed resolution (April, 2013):

  1. Change 6.6 [basic.link] paragraph 5 as follows:

  2. In addition, a member function, static data member, a named class or enumeration of class scope, or an unnamed class or enumeration defined in a class-scope typedef declaration such that the class or enumeration has the typedef name for linkage purposes (9.2.4 [dcl.typedef]), has external linkage if the name of the class has external linkage the same linkage, if any, as the name of the class of which it is a member.
  3. Change the footnote in 6.6 [basic.link] paragraph 8 as follows:

  4. 33) A class template always has external linkage, and the requirements of 13.4.2 [temp.arg.type] and 13.4.3 [temp.arg.nontype] ensure that the template arguments will also have appropriate linkage has the linkage of the innermost enclosing class or namespace in which it is declared.
  5. Change 9.8.2.2 [namespace.unnamed] paragraph 1 as follows:

  6. An unnamed-namespace-definition behaves as if it were replaced by

      inlineopt namespace unique { /* empty body */ }
      using namespace unique ;
      namespace unique { namespace-body }
    

    where inline appears if and only if it appears in the unnamed-namespace-definition, and all occurrences of unique in a translation unit are replaced by the same identifier, and this identifier differs from all other identifiers in the entire program. [Footnote: Although entities in an unnamed namespace might have external linkage, they are effectively qualified by a name unique to their translation unit and therefore can never be seen from any other translation unit. —end footnote] translation unit. [Example:...

  7. Change the note in 11.4.2 [class.mfct] paragraph 3 as follows:

  8. [Note: Member functions of a class in namespace scope have external linkage the linkage of that class. Member functions of a local class (11.6 [class.local]) have no linkage. See 6.6 [basic.link]. —end note]
  9. Change 11.4.9.3 [class.static.data] paragraph 5 as follows:

  10. Static data members of a class in namespace scope have external linkage the linkage of that class (6.6 [basic.link]).
  11. Change 11.8.4 [class.friend] paragraph 4 as follows:

  12. A function first declared in a friend declaration has external linkage the linkage of the namespace of which it is a member (6.6 [basic.link]). Otherwise, the function retains its previous linkage (9.2.2 [dcl.stc]).
  13. Change Clause 13 [temp] paragraph 4 as follows:

  14. A template name has linkage (6.6 [basic.link]). A non-member function template can have internal linkage; any other template name shall have external linkage. Specializations (explicit or implicit) of a template that has internal linkage are distinct from all specializations in other translation units...