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

2026-08-21


3220. Regression in module attachment rules introduced by CWG3171

Section: 6.7  [basic.link]     Status: open     Submitter: Yehuda Bernáth     Date: 2026-08-15

(From thread beginning here.)

Issue 3171 was misguided in turning a normative rule about module attachment into a note. The "precedes" condition is implied, though, once template specializations are attached to the module of the primary template.

Suggested resolution [SUPERSEDED]:

  1. Change in 6.7 [basic.link] paragraph 10 as follows:

    [Note 5: If two declarations correspond but of an entity are attached to different modules, the program is ill-formed if one precedes the other (6.4.1 [basic.scope.scope]). end note] [ Example 2:
      ...
      int g();   // error: corresponds to matches #2, but attached to M
      ...
    
    -- end example]
  2. Change in 10.1 [module.unit] paragraph 7 as follows:

    A module is either a named module or the global module. A declaration is attached to a module as follows:
    • If the declaration is a non-dependent friend declaration that nominates a function with a declarator-id that is a qualified-id or template-id or that nominates a class other than with an elaborated-type-specifier with neither a nested-name-specifier nor a simple-template-id, it is attached to the module to which the friend is attached (6.7 [basic.link]).
    • Otherwise, if the declaration declares a template specialization (13.7.6 [temp.spec.partial], 13.9.4 [temp.expl.spec]), it is attached to the module to which the primary template is attached.
    • Otherwise, if the declaration
      • declares a namespace whose name has external linkage,
      • declares a type alias,
      • declares a namespace alias, or
      • appears within a linkage-specification (9.12 [dcl.link])
      it is attached to the global module.
    • Otherwise, the declaration is attached to the module in whose purview it appears.

Additional notes (2026-08-21)

The suggested resolution does not handle the case of an extern "C" declaration (which is always attached to the global module) vs. a declaration of global-scope variable attached to a named module; see 9.12 [dcl.link] paragraph 7.

Suggested resolution:

  1. Change in 6.7 [basic.link] paragraph 10 as follows:

    [Note 5: If two declarations correspond but of an entity are attached to different modules, the program is ill-formed if one precedes the other (6.4.1 [basic.scope.scope]). end note] [ Example 2:
      ...
      int g();   // error: corresponds to matches #2, but attached to M
      ...
    
    -- end example]
  2. Change in 9.12 [dcl.link] paragraph 7 as follows:

    Two declarations declare the same entity if they (re)introduce the same name, one declares a function or variable with C language linkage, and the other declares such an entity or declares a variable that belongs to the global scope and is attached to the global module. ...
  3. Change in 10.1 [module.unit] paragraph 7 as follows:

    A module is either a named module or the global module. A declaration is attached to a module as follows:
    • If the declaration is a non-dependent friend declaration that nominates a function with a declarator-id that is a qualified-id or template-id or that nominates a class other than with an elaborated-type-specifier with neither a nested-name-specifier nor a simple-template-id, it is attached to the module to which the friend is attached (6.7 [basic.link]).
    • Otherwise, if the declaration declares a template specialization (13.7.6 [temp.spec.partial], 13.9.4 [temp.expl.spec]), it is attached to the module to which the primary template is attached.
    • Otherwise, if the declaration
      • declares a namespace whose name has external linkage,
      • declares a type alias,
      • declares a namespace alias, or
      • appears within a linkage-specification (9.12 [dcl.link])
      it is attached to the global module.
    • Otherwise, the declaration is attached to the module in whose purview it appears.