<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <meta http-equiv="Content-Style-Type" content="text/css" />
  <meta name="generator" content="pandoc" />
  <title>P2615R0: Meaningful exports</title>
  <style type="text/css">code{white-space: pre;}</style>
  <style type="text/css">
  div.del, section.del { background: #fcd; }
  div.ins, section.ins { background: #bfa; }
  .mv { background: #ddf; }
  s, .del { background: #ff8888; margin-right: 0.15ch; }
  u, .ins { background: #88ff88; }
  /* from https://stackoverflow.com/a/32456613 */
  div > blockquote, body > blockquote {
      display: list-item;
      list-style-type: "- ";
  }
  /* With a 3 em gutter and two columns, ANSI letter is 127 characters wide. */
  pre {
  		margin-left: 1.2em;
  }
  .tony {
    border-collapse: collapse;
  }
  .tony > tbody > tr {
    vertical-align: top;
  }
  tr.hr, tr.hr {
    border-bottom: thin solid #60a0b0;  /* relies on collapse */
  }
  </style>
</head>
<body>
<div id="header">
<h1 class="title">P2615R0: Meaningful exports<!-- -*- c++-md -*- --></h1>
</div>
<p><em>Audience</em>: CWG<br />S. Davis Herring &lt;<script type="text/javascript">
<!--
h='&#108;&#x61;&#110;&#108;&#46;&#x67;&#x6f;&#118;';a='&#64;';n='&#104;&#x65;&#114;&#114;&#x69;&#110;&#x67;';e=n+a+h;
document.write('<a h'+'ref'+'="ma'+'ilto'+':'+e+'">'+e+'<\/'+'a'+'>');
// -->
</script><noscript>&#104;&#x65;&#114;&#114;&#x69;&#110;&#x67;&#32;&#x61;&#116;&#32;&#108;&#x61;&#110;&#108;&#32;&#100;&#x6f;&#116;&#32;&#x67;&#x6f;&#118;</noscript>&gt;<br />July 1, 2022</p>
<h1 id="introduction">Introduction</h1>
<p>This paper addresses <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2443">CWG2443</a> by forbidding applying <code>export</code> directly to certain meaningless declarations. Conversely, it also allows all kinds to appear with <code>export {}</code>. For consistency <code>extern &quot;C&quot;</code> is given the same restrictions when used directly.</p>
<h1 id="approach">Approach</h1>
<p>The expansion of permissions here was originally proposed in <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1766r1.html">P1766</a>, which SG2 considered in Cologne but which has never been seen by EWG (perhaps because the rest of it was considered “accepted”). EWG did <a href="https://wiki.edg.com/bin/view/Wg21belfast/ModulesNBinEWG#US081">see the corresponding NB comment</a>, but the vote was too close to progress it. The only apparent new information on the subject is that the wording does not specify a coherent set of restrictions (as opposed to finding the issues that some imagined might surface with the general direction). As such, this wording does make the change (largely by separating the relevant candidates in the <em>declaration</em> grammar); EWG approved the design change (while it had the form of core issue drafting).</p>
<h1 id="wording">Wording</h1>
<p>Relative to N4910.</p>
<h2 id="basic">#[basic]</h2>
<h3 id="basic.pre">#[basic.pre]</h3>
<p>Change paragraph 5:</p>
<blockquote>
<p>Every name is introduced by a <em>declaration</em>, which is a</p>
<ol style="list-style-type: decimal">
<li><em><u>name-</u>declaration</em>,</li>
<li><em>block-<u>name-</u>declaration</em>, or</li>
</ol>
<blockquote>
<p>[…]</p>
</blockquote>
</blockquote>
<h3 id="basic.def">#[basic.def]</h3>
<p>Change bullet (2.20):</p>
<blockquote>
<p>it is an explicit specialization ([temp.expl.spec]) whose <em><u>name-</u>declaration</em> is not a definition.</p>
</blockquote>
<h3 id="basic.lookup.unqual">#[basic.lookup.unqual]</h3>
<p>Change paragraph 1:</p>
<blockquote>
<p>[…]</p>
<p><s>[<em>Note</em>: A <em>using-directive</em> is exported if and only if it appears in a header unit. — <em>end note</em>]</s></p>
</blockquote>
<h2 id="stmt.dcl">#[stmt.dcl]</h2>
<p>Change the grammar in paragraph 1:</p>
<blockquote>
<p><em>declaration-statement</em>:</p>
<blockquote>
<p><em>block-<u>name-</u>declaration</em><br /><u><em>block-special-declaration</em></u></p>
</blockquote>
</blockquote>
<h2 id="dcl.dcl">#[dcl.dcl]</h2>
<h3 id="dcl.pre">#[dcl.pre]</h3>
<p>Change the grammar in paragraph 1:</p>
<blockquote>
<p>[…]</p>
<p><em>declaration</em>:</p>
<blockquote>
<p><u><em>name-declaration</em><br /><em>special-declaration</em></u></p>
</blockquote>
<p><u><em>name-declaration</em>:</u></p>
<blockquote>
<p><em>block-<u>name-</u>declaration</em><br /><em>nodeclspec-function-declaration</em><br /><em>function-definition</em><br /><em>template-declaration</em><br /><u><em>linkage-specification</em><br /><em>namespace-definition</em></u></p>
</blockquote>
<p><u><em>special-declaration</em>:</u></p>
<blockquote>
<p><u><em>block-special-declaration</em></u><br /><em>deduction-guide</em><br /><em>explicit-instantiation</em><br /><em>explicit-specialization</em><br /><em>export-declaration</em><br /><s><em>linkage-specification</em><br /><em>namespace-definition</em></s><br /><em>empty-declaration</em><br /><em>attribute-declaration</em><br /><em>module-import-declaration</em></p>
</blockquote>
<p><em>block-<u>name-</u>declaration</em>:</p>
<blockquote>
<p><em>simple-declaration</em><br /><s><em>asm-declaration</em></s><br /><em>namespace-alias-definition</em><br /><em>using-declaration</em><br /><em>using-enum-declaration</em><br /><em>using-directive</em><br /><s><em>static_assert-declaration</em></s><br /><em>alias-declaration</em><br /><em>opaque-enum-declaration</em></p>
</blockquote>
<p><u><em>block-special-declaration</em>:</u></p>
<blockquote>
<p><u><em>asm-declaration</em><br /><em>static_assert-declaration</em></u></p>
</blockquote>
<p>[…]</p>
</blockquote>
<h3 id="dcl.meaning.general">#[dcl.meaning.general]</h3>
<p>Change paragraph 1:</p>
<blockquote>
<p>A declarator contains exactly one <em>declarator-id</em>; it names the entity that is declared. If the <em>unqualified-id</em> occurring in a <em>declarator-id</em> is a <em>template-id</em>, the declarator shall appear in the <em><u>name-</u>declaration</em> of a <em>template-declaration</em> ([temp.decls]), <em>explicit-specialization</em> ([temp.expl.spec]), or <em>explicit-instantiation</em> ([temp.explicit]).</p>
<p>[…]</p>
</blockquote>
<h3 id="dcl.link">#[dcl.link]</h3>
<p>Change the grammar in paragraph 2:</p>
<blockquote>
<p><em>linkage-specification</em>:</p>
<blockquote>
<p><code>extern</code> <em>string-literal</em> <code>{</code> <em>declaration-seq</em><sub><em>opt</em></sub> <code>}</code><br /><code>extern</code> <em>string-literal</em> <em><u>name-</u>declaration</em></p>
</blockquote>
</blockquote>
<p>Change paragraph 4:</p>
<blockquote>
<p><s>A <em>module-import-declaration</em> shall not be directly contained in a <em>linkage-specification</em>.</s> A <em>module-import-declaration</em> appearing in a linkage specification with other than C++ language linkage is conditionally-supported with implementation-defined semantics.</p>
</blockquote>
<h2 id="module.interface">#[module.interface]</h2>
<p>Change the grammar before paragraph 1:</p>
<blockquote>
<p><em>export-declaration</em>:</p>
<blockquote>
<p><code>export</code> <em><u>name-</u>declaration</em><br /><code>export</code> <code>{</code> <em>declaration-seq</em><sub><em>opt</em></sub> <code>}</code><br /><em>export-keyword</em> <em>module-import-declaration</em></p>
</blockquote>
</blockquote>
<p>Change paragraph 1:</p>
<blockquote>
<p>An <em>export-declaration</em> shall inhabit a namespace scope and appear in the purview of a module interface unit. An <em>export-declaration</em> shall not appear directly or indirectly within an unnamed namespace or a <em>private-module-fragment</em>. An <em>export-declaration</em> has the declarative effects of its <em><u>name-</u>declaration</em>, <em>declaration-seq</em> (if any), or <em>module-import-declaration</em>. <u>The <em>name-declaration</em> of an <em>export-declaration</em> shall not declare a partial specialization ([temp.decls.general]).</u> The <s><em>declaration</em> or </s><em>declaration-seq</em> of an <em>export-declaration</em> shall not contain an <em>export-declaration</em> or <em>module-import-declaration</em>.</p>
<p>[<em>Note</em>: An <em>export-declaration</em> does not establish a scope. — <em>end note</em>]</p>
</blockquote>
<p>Change paragraph 3:</p>
<blockquote>
<p><s>An exported declaration that is not a <em>module-import-declaration</em> shall declare at least one name.</s> If <s>the</s><u>an exported</u> declaration is not within a header unit, it shall not declare a name with internal linkage.</p>
</blockquote>
<p>Change paragraph 4:</p>
<blockquote>
[…]
<pre class="cpp">
export module M;
export namespace {}             // error: <s>does not introduce any names</s><u>namespace has internal linkage</u>
<s>export namespace {
  int a1;                       // error: export of name with internal linkage
}
</s>namespace {
  export int a2;                // error: export of name with internal linkage
}
export static int b;            // error: b explicitly declared static
export int f();                 // OK
export namespace N { }          // OK
export using namespace N;       // <s>error: does not declare a name</s><u>OK</u>
</pre>
<p>[…]</p>
</blockquote>
<h2 id="temp">#[temp]</h2>
<h3 id="temp.explicit">#[temp.explicit]</h3>
<p>Change the grammar in paragraph 2:</p>
<blockquote>
<p><em>explicit-instantiation</em>:</p>
<blockquote>
<p><code>extern</code><sub><em>opt</em></sub> <code>template</code> <em><u>name-</u>declaration</em></p>
</blockquote>
</blockquote>
<p>Change paragraph 4:</p>
<blockquote>
<p>If the explicit instantiation is for a class or member class, the <em>elaborated-type-specifier</em> in the <em><u>name-</u>declaration</em> shall include a <em>simple-template-id</em>; otherwise, the <em><u>name-</u>declaration</em> shall be a <em>simple-declaration</em> whose <em>init-declarator-list</em> comprises a single <em>init-declarator</em> that does not have an <em>initializer</em>. If the explicit instantiation is for a variable template specialization, the <em>unqualified-id</em> in the <em>declarator</em> shall be a <em>simple-template-id</em>. [<em>Example</em>:</p>
<p>[…]</p>
<p>— <em>end example</em>]</p>
</blockquote>
<p>Change paragraph 5:</p>
<blockquote>
<p>[…] If the <em><u>name-</u>declaration</em> of the explicit instantiation names an implicitly-declared special member function ([special]), the program is ill-formed.</p>
</blockquote>
<p>Change paragraph 6:</p>
<blockquote>
<p>The <em><u>name-</u>declaration</em> in an <em>explicit-instantiation</em> and the <em>declaration</em> produced by the corresponding substitution into the templated function, variable, or class are two declarations of the same entity.</p>
<p>[<em>Note</em>: […] — <em>end note</em>]</p>
<p>Despite its syntactic form, the <em><u>name-</u>declaration</em> in an <em>explicit-instantiation</em> for a variable is not itself a definition and does not conflict with the definition instantiated by an explicit instantiation definition for that variable.</p>
</blockquote>
<h3 id="temp.expl.spec">#[temp.expl.spec]</h3>
<p>Change paragraph 2:</p>
<blockquote>
<p><u>The <em>declaration</em> in an <em>explicit-specialization</em> shall not be an <em>export-declaration</em>.</u> An explicit specialization shall not use a <em>storage-class-specifier</em> ([dcl.stc]) other than <code>thread_local</code>.</p>
</blockquote>
</body>
</html>
