Date: Thu, 20 Aug 2026 19:51:56 -0400
Thanks for pointing this out. There's now a CWG issue for it:
https://cplusplus.github.io/CWG/issues/3220
On Sat, Aug 15, 2026 at 3:44 PM Yehuda BernĂ¡th via Std-Discussion <
std-discussion_at_[hidden]> wrote:
> [basic.link]/10 <https://eel.is/c++draft/basic.link#10> states:
>
>> As a consequence of these rules, all declarations of an entity are
>> attached to the same
>> module;
>
>
> How does it follow from those rules? Paragraph 8
> <https://eel.is/c++draft/basic.link#8> gives three cases where two
> corresponding declarations with the same target scope declare the same
> entity:
>
> 1. if they appear in the same translation unit,
> 2. if they both declare aliases to the same type or namespace, *or*
> 3. if they both have module or external linkage *and are attached to
> the same module.*
>
> So only the case 3 is explicitly restricted to declaration that are
> attached to the same module. In case 2 this is trivially true since aliases
> are always attached to the global module. But what about case 1? Two
> declarations in the same translation unit can easily be attached to
> different modules if the TU is a module unit and one of them appears in the
> global module fragment or inside a language linkage specifier, for example:
>
> module M;
> int x;
> extern "C++" int x;
>
> Or:
>
> module;
> void f();
> module M;
> void f();
>
> Note 5 <https://eel.is/c++draft/basic.link#note-5> tries to address such
> cases by saying:
>
>> If two declarations correspond but are attached to different modules, the
>> program is ill-formed if one precedes the other ([basic.scope.scope]
>> <https://eel.is/c++draft/basic.scope.scope>).
>
> But clause [basic.scope.scope] doesn't contain any rule that makes such
> cases ill-formed. The only relevant paragraph there is 6
> <https://eel.is/c++draft/basic.scope.scope#6>, which states:
>
>> Two declarations *potentially conflict* if they correspond and cause
>> their shared name to denote different entities ([basic.link]
>> <https://eel.is/c++draft/basic.link>). The program is ill-formed if, in
>> any scope, a name is bound to two declarations A and B that potentially
>> conflict and A precedes B ([basic.lookup]
>> <https://eel.is/c++draft/basic.lookup>), unless B is name-independent.
>
> But for it to apply the two declarations need to already denote different
> entities, and it explicitly refers to [basic.link] for the definition of
> when that occurs. So it seems like nothing in the normative wording
> prevents declarations of an entity from being attached to different
> modules, making the statement in [basic.link]/10
> <https://eel.is/c++draft/basic.link#10> false and the definition that
> follows there ambiguous.
> --
> Std-Discussion mailing list
> Std-Discussion_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>
https://cplusplus.github.io/CWG/issues/3220
On Sat, Aug 15, 2026 at 3:44 PM Yehuda BernĂ¡th via Std-Discussion <
std-discussion_at_[hidden]> wrote:
> [basic.link]/10 <https://eel.is/c++draft/basic.link#10> states:
>
>> As a consequence of these rules, all declarations of an entity are
>> attached to the same
>> module;
>
>
> How does it follow from those rules? Paragraph 8
> <https://eel.is/c++draft/basic.link#8> gives three cases where two
> corresponding declarations with the same target scope declare the same
> entity:
>
> 1. if they appear in the same translation unit,
> 2. if they both declare aliases to the same type or namespace, *or*
> 3. if they both have module or external linkage *and are attached to
> the same module.*
>
> So only the case 3 is explicitly restricted to declaration that are
> attached to the same module. In case 2 this is trivially true since aliases
> are always attached to the global module. But what about case 1? Two
> declarations in the same translation unit can easily be attached to
> different modules if the TU is a module unit and one of them appears in the
> global module fragment or inside a language linkage specifier, for example:
>
> module M;
> int x;
> extern "C++" int x;
>
> Or:
>
> module;
> void f();
> module M;
> void f();
>
> Note 5 <https://eel.is/c++draft/basic.link#note-5> tries to address such
> cases by saying:
>
>> If two declarations correspond but are attached to different modules, the
>> program is ill-formed if one precedes the other ([basic.scope.scope]
>> <https://eel.is/c++draft/basic.scope.scope>).
>
> But clause [basic.scope.scope] doesn't contain any rule that makes such
> cases ill-formed. The only relevant paragraph there is 6
> <https://eel.is/c++draft/basic.scope.scope#6>, which states:
>
>> Two declarations *potentially conflict* if they correspond and cause
>> their shared name to denote different entities ([basic.link]
>> <https://eel.is/c++draft/basic.link>). The program is ill-formed if, in
>> any scope, a name is bound to two declarations A and B that potentially
>> conflict and A precedes B ([basic.lookup]
>> <https://eel.is/c++draft/basic.lookup>), unless B is name-independent.
>
> But for it to apply the two declarations need to already denote different
> entities, and it explicitly refers to [basic.link] for the definition of
> when that occurs. So it seems like nothing in the normative wording
> prevents declarations of an entity from being attached to different
> modules, making the statement in [basic.link]/10
> <https://eel.is/c++draft/basic.link#10> false and the definition that
> follows there ambiguous.
> --
> Std-Discussion mailing list
> Std-Discussion_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>
-- *Brian Bi*
Received on 2026-08-20 23:52:13
