<!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>P2615R1: 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">P2615R1: Meaningful exports<!-- -*- c++-md -*- --></h1>
</div>
<p><em>Audience</em>: EWG, 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 />November 11, 2022</p>
<h1 id="history">History</h1>
<p>Since <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2615r0.html">r0</a>:</p>
<ul>
<li>Removed outdated change to [basic.def]</li>
<li>Allowed bare <code>export</code> of certain declarations requested by EWG (and <em>deduction-guide</em>s, whose status is unclear, for the sake of discussion)</li>
</ul>
<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. No issues have surfaced with the general direction, but the wording does not specify a coherent set of restrictions; as such, this wording makes most of the change (largely by separating the relevant candidates in the <em>declaration</em> grammar). EWG has seen this proposal several times, with varied outcomes; the most recent (in Kona 2022) requested to allow certain declarations unlikely to mislead programmers into thinking they have some effect.</p>
<h1 id="wording">Wording</h1>
<p>Relative to N4917.</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>
</ol>
</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="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-declaration</em><br /><em>nodeclspec-function-declaration</em><br /><em>function-definition</em><br /><em>template-declaration</em><br /><em>deduction-guide</em><br /><s><em>explicit-instantiation</em><br /><em>explicit-specialization</em><br /><em>export-declaration</em></s><br /><em>linkage-specification</em><br /><em>namespace-definition</em><br /><em>empty-declaration</em><br /><em>attribute-declaration</em><br /><em>module-import-declaration</em></p>
</blockquote>
<p><u><em>special-declaration</em>:</u></p>
<blockquote>
<p><u><em>explicit-instantiation</em><br /><em>explicit-specialization</em><br /><em>export-declaration</em></u></p>
</blockquote>
<p><em>block-declaration</em>:</p>
<blockquote>
<p><em>simple-declaration</em><br /><em>asm-declaration</em><br /><em>namespace-alias-definition</em><br /><em>using-declaration</em><br /><em>using-enum-declaration</em><br /><em>using-directive</em><br /><em>static_assert-declaration</em><br /><em>alias-declaration</em><br /><em>opaque-enum-declaration</em></p>
</blockquote>
<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.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>
