Modules TS: module linkage and export declarations

59 views
Skip to first unread message

Richard Smith

unread,
Oct 6, 2017, 5:27:39 PM10/6/17
to C++ Core Language Working Group, mod...@isocpp.org, Gabriel Dos Reis
What is expected to happen here:

export module M;
void f(); // #1
export void f(); // #2

Is #2 supposed to be valid, exporting the already-declared function #1?

To my reading, declaration #1 declares f() to have module linkage.

What happens next depends on how you read Modules TS [basic.link] (6.5) paragraph 8.

Case 1: Suppose we think that the name "f" of the declaration #2 was "introduced by a non-exported declaration" -- specifically, declaration #1. Then #2 also receives module linkage.

Then [dcl.module.interface]p1 says "The names of all entities in the interface of a module are visible
to any translation unit importing that module. [...] The entity and the declaration introduced by
an export-declaration are said to be exported."

So f is exported and is visible to translation units that import M.

Finally, [dcl.module.interface]p2 says "Every name introduced by an export-declaration shall have external linkage." But we already said that #2 did not "introduce" a name. So we end up with M exporting a declaration with module linkage, contradicting the definition of module linkage.

Case 2: Suppose we think that declaration #2 introduces the name "f". Then #2 receives external linkage, and can be exported.

But then we have the same entity having two different linkages in two successive declarations, and no rule saying that's invalid. ([basic.link]p6 says you can't have an entity declared with both internal linkage and external linkage, but here "f" is declared with module linkage and external linkage.)

This has many problematic consequences, not least of which is that its name mangling may change after it's declared.


So: what is the intended behavior here, and by what mechanism is the wording intended to give that result? Should we clarify that case 2 is the expected interpretation and generalize [basic.link]p6 to say that the same entity shall not be declared with two different linkages within a translation unit?

Gabriel Dos Reis

unread,
Oct 6, 2017, 5:29:35 PM10/6/17
to Richard Smith, C++ Core Language Working Group, mod...@isocpp.org

‘#2’ is an error because it changes the linkage of the function ‘f’.

Richard Smith

unread,
Oct 6, 2017, 5:31:16 PM10/6/17
to Gabriel Dos Reis, C++ Core Language Working Group, mod...@isocpp.org
OK, sounds good. I think we need a wording update to say that. Can you add an issue to the modules issues list? Thanks!

Gabriel Dos Reis

unread,
Oct 6, 2017, 5:32:02 PM10/6/17
to Richard Smith, C++ Core Language Working Group, mod...@isocpp.org

Done.  Thanks!

 

From: Richard Smith [mailto:richar...@google.com]

Richard Smith

unread,
Oct 6, 2017, 5:34:33 PM10/6/17
to Gabriel Dos Reis, C++ Core Language Working Group, mod...@isocpp.org
Just for completeness: is

export module M;
export void f();
void f();

valid, with the second declaration of f inheriting external linkage from the first?

Gabriel Dos Reis

unread,
Oct 6, 2017, 6:08:31 PM10/6/17
to mod...@isocpp.org, C++ Core Language Working Group

Yes, it is valid, because it is inheriting the module linkage.  It is a necessity too:

 

     // module interface unit

     export module M;

     export void f();

 

     // module implementation unit

     module M;

     void f() { }  // definition, therefore declaration – export not allowed here.

 

--
You received this message because you are subscribed to the Google Groups "SG2 - Modules" group.
To unsubscribe from this group and stop receiving emails from it, send an email to modules+u...@isocpp.org.
To post to this group, send email to mod...@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/modules/.

Reply all
Reply to author
Forward
0 new messages