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

2024-12-21


2973. Does an alias-declaration introduce a name for linkage purposes?

Section: 9.2.4  [dcl.typedef]     Status: open     Submitter: Jonathan Wakely     Date: 2024-12-19

Consider:

   using A = struct { int i; };

Does the unnamed class have A as its name for linkage purposes? There is implementation divergence.

Possible resolution (option 1):

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

    ... The name of an entity that belongs to a namespace scope, that has not been given internal linkage above, and that is the name of
    • a variable; or
    • a function; or
    • a named class (11.1 [class.pre]), or an unnamed class defined in a typedef declaration or alias-declaration in which the class has the typedef name for linkage purposes (9.2.4 [dcl.typedef]); or
    • a named enumeration (9.7.1 [dcl.enum]), or an unnamed enumeration defined in a typedef declaration or alias-declaration in which the enumeration has the typedef name for linkage purposes (9.2.4 [dcl.typedef]); or
    • an unnamed enumeration that has an enumerator as a name for linkage purposes (9.7.1 [dcl.enum]); or
    • a template
    has its linkage determined as follows: ...
  2. Change in 6.6 [basic.link] paragraph 5 as follows:

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

    ... [Note 3: The type of a pointer or reference to array of unknown bound permanently points to or refers to an incomplete type. An array of unknown bound named by a typedef declaration or alias-declaration permanently refers to an incomplete type. In either case, the array type cannot be completed. —end note] ...
  4. Change in 9.2.4 [dcl.typedef] paragraph 4 as follows:

    An unnamed class or enumeration C defined in a typedef declaration or alias-declaration has the first typedef-name declared by the declaration to be of type C as its typedef name for linkage purposes (6.6 [basic.link]). [Note 2: A typedef declaration or alias-declaration involving a lambda-expression does not itself define the associated closure type, and so the closure type is not given a typedef name for linkage purposes. —end note] [Example 4:
      typedef struct { } *ps, S;    // S is the typedef name for linkage purposes
      typedef decltype([]{}) C;     // the closure type has no typedef name for linkage purposes
      using U = class { };          // U is the typedef name for linkage purposes
    
    end example]

Possible resolution (option 2):

  1. Change in 6.2 [basic.def] paragraph 2 as follows:

    Each entity declared by a declaration is also defined by that declaration unless:
    • ...
    • it is a typedef an alias declaration (9.2.4 [dcl.typedef]),
    • it is an alias-declaration (9.2.4 [dcl.typedef]),
    • ...
  2. Change in 6.6 [basic.link] paragraph 4 as follows:

    ... The name of an entity that belongs to a namespace scope, that has not been given internal linkage above, and that is the name of
    • a variable; or
    • a function; or
    • a named class (11.1 [class.pre]), or an unnamed class defined in a typedef an alias declaration in which the class has the typedef name for linkage purposes (9.2.4 [dcl.typedef]); or
    • a named enumeration (9.7.1 [dcl.enum]), or an unnamed enumeration defined in a typedef an alias declaration in which the enumeration has the typedef name for linkage purposes (9.2.4 [dcl.typedef]); or
    • an unnamed enumeration that has an enumerator as a name for linkage purposes (9.7.1 [dcl.enum]); or
    • a template
    has its linkage determined as follows: ...
  3. Change in 6.6 [basic.link] paragraph 5 as follows:

    In addition, a member function, a static data member, a named class or enumeration that inhabits a class scope, or an unnamed class or enumeration defined in a typedef an alias declaration that inhabits a class scope such that the class or enumeration has the typedef name for linkage purposes (9.2.4 [dcl.typedef]), has the same linkage, if any, as the name of the class of which it is a member.
  4. Change in 6.8.1 [basic.types.general] paragraph 6 as follows:

    ... [Note 3: The type of a pointer or reference to array of unknown bound permanently points to or refers to an incomplete type. An array of unknown bound named by a typedef an alias declaration (9.2.4 [dcl.typedef]) permanently refers to an incomplete type. In either case, the array type cannot be completed. —end note] ...
  5. Change in 9.1 [dcl.pre] paragraph 5 as follows:

    If the decl-specifier-seq contains the typedef specifier, see 9.2.4 [dcl.typedef]. the declaration is a typedef declaration and each declarator-id is declared to be a typedef-name, synonymous with its associated type (9.2.4 [dcl.typedef]). [Note 4: Such a declarator-id is an identifier (11.4.8.3 [class.conv.fct]). —end note] Otherwise, if the type associated with a declarator-id is a function type (9.3.4.6 [dcl.fct]), the declaration is a function declaration. Otherwise, if the type associated with a declarator-id is an object or reference type, the declaration is an object declaration. Otherwise, the program is ill-formed.
  6. Add a new paragraph after 9.2.4 [dcl.typedef] paragraph 2 as follows:

    ... The defining-type-specifier-seq of the defining-type-id shall not define a class or enumeration if the alias-declaration is the declaration of a template-declaration.

    An alias declaration is a typedef declaration or an alias-declaration.

  7. Change in 9.2.4 [dcl.typedef] paragraph 4 as follows:

    An unnamed class or enumeration C defined in a typedef an alias declaration has the first typedef-name declared by the declaration to be of type C as its typedef name for linkage purposes (6.6 [basic.link]). [Note 2: A typedef An alias declaration involving a lambda-expression does not itself define the associated closure type, and so the closure type is not given a typedef name for linkage purposes. —end note] [Example 4:
      typedef struct { } *ps, S;    // S is the typedef name for linkage purposes
      typedef decltype([]{}) C;     // the closure type has no typedef name for linkage purposes
      using U = class { };          // U is the typedef name for linkage purposes
    
    end example]