<!doctype html><html lang="en">
 <head>
  <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  <meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name="viewport">
  <title>P0947R1: Another take on Modules</title>
<style data-fill-with="stylesheet">/******************************************************************************
 *                   Style sheet for the W3C specifications                   *
 *
 * Special classes handled by this style sheet include:
 *
 * Indices
 *   - .toc for the Table of Contents (<ol class="toc">)
 *     + <span class="secno"> for the section numbers
 *   - #toc for the Table of Contents (<nav id="toc">)
 *   - ul.index for Indices (<a href="#ref">term</a><span>, in §N.M</span>)
 *   - table.index for Index Tables (e.g. for properties or elements)
 *
 * Structural Markup
 *   - table.data for general data tables
 *     -> use 'scope' attribute, <colgroup>, <thead>, and <tbody> for best results !
 *     -> use <table class='complex data'> for extra-complex tables
 *     -> use <td class='long'> for paragraph-length cell content
 *     -> use <td class='pre'> when manual line breaks/indentation would help readability
 *   - dl.switch for switch statements
 *   - ol.algorithm for algorithms (helps to visualize nesting)
 *   - .figure and .caption (HTML4) and figure and figcaption (HTML5)
 *     -> .sidefigure for right-floated figures
 *   - ins/del
 *
 * Code
 *   - pre and code
 *
 * Special Sections
 *   - .note       for informative notes             (div, p, span, aside, details)
 *   - .example    for informative examples          (div, p, pre, span)
 *   - .issue      for issues                        (div, p, span)
 *   - .assertion  for assertions                    (div, p, span)
 *   - .advisement for loud normative statements     (div, p, strong)
 *   - .annoying-warning for spec obsoletion notices (div, aside, details)
 *
 * Definition Boxes
 *   - pre.def   for WebIDL definitions
 *   - table.def for tables that define other entities (e.g. CSS properties)
 *   - dl.def    for definition lists that define other entitles (e.g. HTML elements)
 *
 * Numbering
 *   - .secno for section numbers in .toc and headings (<span class='secno'>3.2</span>)
 *   - .marker for source-inserted example/figure/issue numbers (<span class='marker'>Issue 4</span>)
 *   - ::before styled for CSS-generated issue/example/figure numbers:
 *     -> Documents wishing to use this only need to add
 *        figcaption::before,
 *        .caption::before { content: "Figure "  counter(figure) " ";  }
 *        .example::before { content: "Example " counter(example) " "; }
 *        .issue::before   { content: "Issue "   counter(issue) " ";   }
 *
 * Header Stuff (ignore, just don't conflict with these classes)
 *   - .head for the header
 *   - .copyright for the copyright
 *
 * Miscellaneous
 *   - .overlarge for things that should be as wide as possible, even if
 *     that overflows the body text area. This can be used on an item or
 *     on its container, depending on the effect desired.
 *     Note that this styling basically doesn't help at all when printing,
 *     since A4 paper isn't much wider than the max-width here.
 *     It's better to design things to fit into a narrower measure if possible.
 *   - js-added ToC jump links (see fixup.js)
 *
 ******************************************************************************/

/******************************************************************************/
/*                                   Body                                     */
/******************************************************************************/

	body {
		counter-reset: example figure issue;

		/* Layout */
		max-width: 50em;               /* limit line length to 50em for readability   */
		margin: 0 auto;                /* center text within page                     */
		padding: 1.6em 1.5em 2em 50px; /* assume 16px font size for downlevel clients */
		padding: 1.6em 1.5em 2em calc(26px + 1.5em); /* leave space for status flag     */

		/* Typography */
		line-height: 1.5;
		font-family: sans-serif;
		widows: 2;
		orphans: 2;
		word-wrap: break-word;
		overflow-wrap: break-word;
		hyphens: auto;

		/* Colors */
		color: black;
		background: white top left fixed no-repeat;
		background-size: 25px auto;
	}


/******************************************************************************/
/*                         Front Matter & Navigation                          */
/******************************************************************************/

/** Header ********************************************************************/

	div.head { margin-bottom: 1em }
	div.head hr { border-style: solid; }

	div.head h1 {
		font-weight: bold;
		margin: 0 0 .1em;
		font-size: 220%;
	}

	div.head h2 { margin-bottom: 1.5em;}

/** W3C Logo ******************************************************************/

	.head .logo {
		float: right;
		margin: 0.4rem 0 0.2rem .4rem;
	}

	.head img[src*="logos/W3C"] {
		display: block;
		border: solid #1a5e9a;
		border-width: .65rem .7rem .6rem;
		border-radius: .4rem;
		background: #1a5e9a;
		color: white;
		font-weight: bold;
	}

	.head a:hover > img[src*="logos/W3C"],
	.head a:focus > img[src*="logos/W3C"] {
		opacity: .8;
	}

	.head a:active > img[src*="logos/W3C"] {
		background: #c00;
		border-color: #c00;
	}

	/* see also additional rules in Link Styling section */

/** Copyright *****************************************************************/

	p.copyright,
	p.copyright small { font-size: small }

/** Back to Top / ToC Toggle **************************************************/

	@media print {
		#toc-nav {
			display: none;
		}
	}
	@media not print {
		#toc-nav {
			position: fixed;
			z-index: 2;
			bottom: 0; left: 0;
			margin: 0;
			min-width: 1.33em;
			border-top-right-radius: 2rem;
			box-shadow: 0 0 2px;
			font-size: 1.5em;
			color: black;
		}
		#toc-nav > a {
			display: block;
			white-space: nowrap;

			height: 1.33em;
			padding: .1em 0.3em;
			margin: 0;

			background: white;
			box-shadow: 0 0 2px;
			border: none;
			border-top-right-radius: 1.33em;
			background: white;
		}
		#toc-nav > #toc-jump {
			padding-bottom: 2em;
			margin-bottom: -1.9em;
		}

		#toc-nav > a:hover,
		#toc-nav > a:focus {
			background: #f8f8f8;
		}
		#toc-nav > a:not(:hover):not(:focus) {
			color: #707070;
		}

		/* statusbar gets in the way on keyboard focus; remove once browsers fix */
		#toc-nav > a[href="#toc"]:not(:hover):focus:last-child {
			padding-bottom: 1.5rem;
		}

		#toc-nav:not(:hover) > a:not(:focus) > span + span {
			/* Ideally this uses :focus-within on #toc-nav */
			display: none;
		}
		#toc-nav > a > span + span {
			padding-right: 0.2em;
		}

		#toc-toggle-inline {
			vertical-align: 0.05em;
			font-size: 80%;
			color: gray;
			color: hsla(203,20%,40%,.7);
			border-style: none;
			background: transparent;
			position: relative;
		}
		#toc-toggle-inline:hover:not(:active),
		#toc-toggle-inline:focus:not(:active) {
			text-shadow: 1px 1px silver;
			top: -1px;
			left: -1px;
		}

		#toc-nav :active {
			color: #C00;
		}
	}

/** ToC Sidebar ***************************************************************/

	/* Floating sidebar */
	@media screen {
		body.toc-sidebar #toc {
			position: fixed;
			top: 0; bottom: 0;
			left: 0;
			width: 23.5em;
			max-width: 80%;
			max-width: calc(100% - 2em - 26px);
			overflow: auto;
			padding: 0 1em;
			padding-left: 42px;
			padding-left: calc(1em + 26px);
			background: inherit;
			background-color: #f7f8f9;
			z-index: 1;
			box-shadow: -.1em 0 .25em rgba(0,0,0,.1) inset;
		}
		body.toc-sidebar #toc h2 {
			margin-top: .8rem;
			font-variant: small-caps;
			font-variant: all-small-caps;
			text-transform: lowercase;
			font-weight: bold;
			color: gray;
			color: hsla(203,20%,40%,.7);
		}
		body.toc-sidebar #toc-jump:not(:focus) {
			width: 0;
			height: 0;
			padding: 0;
			position: absolute;
			overflow: hidden;
		}
	}
	/* Hide main scroller when only the ToC is visible anyway */
	@media screen and (max-width: 28em) {
		body.toc-sidebar {
			overflow: hidden;
		}
	}

	/* Sidebar with its own space */
	@media screen and (min-width: 78em) {
		body:not(.toc-inline) #toc {
			position: fixed;
			top: 0; bottom: 0;
			left: 0;
			width: 23.5em;
			overflow: auto;
			padding: 0 1em;
			padding-left: 42px;
			padding-left: calc(1em + 26px);
			background: inherit;
			background-color: #f7f8f9;
			z-index: 1;
			box-shadow: -.1em 0 .25em rgba(0,0,0,.1) inset;
		}
		body:not(.toc-inline) #toc h2 {
			margin-top: .8rem;
			font-variant: small-caps;
			font-variant: all-small-caps;
			text-transform: lowercase;
			font-weight: bold;
			color: gray;
			color: hsla(203,20%,40%,.7);
		}

		body:not(.toc-inline) {
			padding-left: 29em;
		}
		/* See also Overflow section at the bottom */

		body:not(.toc-inline) #toc-jump:not(:focus) {
			width: 0;
			height: 0;
			padding: 0;
			position: absolute;
			overflow: hidden;
		}
	}
	@media screen and (min-width: 90em) {
		body:not(.toc-inline) {
			margin: 0 4em;
		}
	}

/******************************************************************************/
/*                                Sectioning                                  */
/******************************************************************************/

/** Headings ******************************************************************/

	h1, h2, h3, h4, h5, h6, dt {
		page-break-after: avoid;
		page-break-inside: avoid;
		font: 100% sans-serif;   /* Reset all font styling to clear out UA styles */
		font-family: inherit;    /* Inherit the font family. */
		line-height: 1.2;        /* Keep wrapped headings compact */
		hyphens: manual;         /* Hyphenated headings look weird */
	}

	h2, h3, h4, h5, h6 {
		margin-top: 3rem;
	}

	h1, h2, h3 {
		color: #005A9C;
		background: transparent;
	}

	h1 { font-size: 170%; }
	h2 { font-size: 140%; }
	h3 { font-size: 120%; }
	h4 { font-weight: bold; }
	h5 { font-style: italic; }
	h6 { font-variant: small-caps; }
	dt { font-weight: bold; }

/** Subheadings ***************************************************************/

	h1 + h2,
	#subtitle {
		/* #subtitle is a subtitle in an H2 under the H1 */
		margin-top: 0;
	}
	h2 + h3,
	h3 + h4,
	h4 + h5,
	h5 + h6 {
		margin-top: 1.2em; /* = 1 x line-height */
	}

/** Section divider ***********************************************************/

	:not(.head) > hr {
		font-size: 1.5em;
		text-align: center;
		margin: 1em auto;
		height: auto;
		border: transparent solid 0;
		background: transparent;
	}
	:not(.head) > hr::before {
		content: "\2727\2003\2003\2727\2003\2003\2727";
	}

/******************************************************************************/
/*                            Paragraphs and Lists                            */
/******************************************************************************/

	p {
		margin: 1em 0;
	}

	dd > p:first-child,
	li > p:first-child {
		margin-top: 0;
	}

	ul, ol {
		margin-left: 0;
		padding-left: 2em;
	}

	li {
		margin: 0.25em 0 0.5em;
		padding: 0;
	}

	dl dd {
		margin: 0 0 .5em 2em;
	}

	.head dd + dd { /* compact for header */
		margin-top: -.5em;
	}

	/* Style for algorithms */
	ol.algorithm ol:not(.algorithm),
	.algorithm > ol ol:not(.algorithm) {
	 border-left: 0.5em solid #DEF;
	}

	/* Put nice boxes around each algorithm. */
	[data-algorithm]:not(.heading) {
	  padding: .5em;
	  border: thin solid #ddd; border-radius: .5em;
	  margin: .5em calc(-0.5em - 1px);
	}
	[data-algorithm]:not(.heading) > :first-child {
	  margin-top: 0;
	}
	[data-algorithm]:not(.heading) > :last-child {
	  margin-bottom: 0;
	}

	/* Style for switch/case <dl>s */
	dl.switch > dd > ol.only,
	dl.switch > dd > .only > ol {
	 margin-left: 0;
	}
	dl.switch > dd > ol.algorithm,
	dl.switch > dd > .algorithm > ol {
	 margin-left: -2em;
	}
	dl.switch {
	 padding-left: 2em;
	}
	dl.switch > dt {
	 text-indent: -1.5em;
	 margin-top: 1em;
	}
	dl.switch > dt + dt {
	 margin-top: 0;
	}
	dl.switch > dt::before {
	 content: '\21AA';
	 padding: 0 0.5em 0 0;
	 display: inline-block;
	 width: 1em;
	 text-align: right;
	 line-height: 0.5em;
	}

/** Terminology Markup ********************************************************/


/******************************************************************************/
/*                                 Inline Markup                              */
/******************************************************************************/

/** Terminology Markup ********************************************************/
	dfn   { /* Defining instance */
		font-weight: bolder;
	}
	a > i { /* Instance of term */
		font-style: normal;
	}
	dt dfn code, code.idl {
		font-size: medium;
	}
	dfn var {
		font-style: normal;
	}

/** Change Marking ************************************************************/

	del { color: red;  text-decoration: line-through; }
	ins { color: #080; text-decoration: underline;    }

/** Miscellaneous improvements to inline formatting ***************************/

	sup {
		vertical-align: super;
		font-size: 80%
	}

/******************************************************************************/
/*                                    Code                                    */
/******************************************************************************/

/** General monospace/pre rules ***********************************************/

	pre, code, samp {
		font-family: Menlo, Consolas, "DejaVu Sans Mono", Monaco, monospace;
		font-size: .9em;
		page-break-inside: avoid;
		hyphens: none;
		text-transform: none;
	}
	pre code,
	code code {
		font-size: 100%;
	}

	pre {
		margin-top: 1em;
		margin-bottom: 1em;
		overflow: auto;
	}

/** Inline Code fragments *****************************************************/

  /* Do something nice. */

/******************************************************************************/
/*                                    Links                                   */
/******************************************************************************/

/** General Hyperlinks ********************************************************/

	/* We hyperlink a lot, so make it less intrusive */
	a[href] {
		color: #034575;
		text-decoration: none;
		border-bottom: 1px solid #707070;
		/* Need a bit of extending for it to look okay */
		padding: 0 1px 0;
		margin: 0 -1px 0;
	}
	a:visited {
		border-bottom-color: #BBB;
	}

	/* Use distinguishing colors when user is interacting with the link */
	a[href]:focus,
	a[href]:hover {
		background: #f8f8f8;
		background: rgba(75%, 75%, 75%, .25);
		border-bottom-width: 3px;
		margin-bottom: -2px;
	}
	a[href]:active {
		color: #C00;
		border-color: #C00;
	}

	/* Backout above styling for W3C logo */
	.head .logo,
	.head .logo a {
		border: none;
		text-decoration: none;
		background: transparent;
	}

/******************************************************************************/
/*                                    Images                                  */
/******************************************************************************/

	img {
		border-style: none;
	}

	/* For autogen numbers, add
	   .caption::before, figcaption::before { content: "Figure " counter(figure) ". "; }
	*/

	figure, .figure, .sidefigure {
		page-break-inside: avoid;
		text-align: center;
		margin: 2.5em 0;
	}
	.figure img,    .sidefigure img,    figure img,
	.figure object, .sidefigure object, figure object {
		max-width: 100%;
		margin: auto;
	}
	.figure pre, .sidefigure pre, figure pre {
		text-align: left;
		display: table;
		margin: 1em auto;
	}
	.figure table, figure table {
		margin: auto;
	}
	@media screen and (min-width: 20em) {
		.sidefigure {
			float: right;
			width: 50%;
			margin: 0 0 0.5em 0.5em
		}
	}
	.caption, figcaption, caption {
		font-style: italic;
		font-size: 90%;
	}
	.caption::before, figcaption::before, figcaption > .marker {
		font-weight: bold;
	}
	.caption, figcaption {
		counter-increment: figure;
	}

	/* DL list is indented 2em, but figure inside it is not */
	dd > .figure, dd > figure { margin-left: -2em }

/******************************************************************************/
/*                             Colored Boxes                                  */
/******************************************************************************/

	.issue, .note, .example, .assertion, .advisement, blockquote {
		padding: .5em;
		border: .5em;
		border-left-style: solid;
		page-break-inside: avoid;
	}
	span.issue, span.note {
		padding: .1em .5em .15em;
		border-right-style: solid;
	}

	.issue,
	.note,
	.example,
	.advisement,
	.assertion,
	blockquote {
		margin: 1em auto;
	}
	.note  > p:first-child,
	.issue > p:first-child,
	blockquote > :first-child {
		margin-top: 0;
	}
	blockquote > :last-child {
		margin-bottom: 0;
	}

/** Blockquotes ***************************************************************/

	blockquote {
		border-color: silver;
	}

/** Open issue ****************************************************************/

	.issue {
		border-color: #E05252;
		background: #FBE9E9;
		counter-increment: issue;
		overflow: auto;
	}
	.issue::before, .issue > .marker {
		text-transform: uppercase;
		color: #AE1E1E;
		padding-right: 1em;
		text-transform: uppercase;
	}
	/* Add .issue::before { content: "Issue " counter(issue) " "; } for autogen numbers,
	   or use class="marker" to mark up the issue number in source. */

/** Example *******************************************************************/

	.example {
		border-color: #E0CB52;
		background: #FCFAEE;
		counter-increment: example;
		overflow: auto;
		clear: both;
	}
	.example::before, .example > .marker {
		text-transform: uppercase;
		color: #827017;
		min-width: 7.5em;
		display: block;
	}
	/* Add .example::before { content: "Example " counter(example) " "; } for autogen numbers,
	   or use class="marker" to mark up the example number in source. */

/** Non-normative Note ********************************************************/

	.note {
		border-color: #52E052;
		background: #E9FBE9;
		overflow: auto;
	}

	.note::before, .note > .marker,
	details.note > summary::before,
	details.note > summary > .marker {
		text-transform: uppercase;
		display: block;
		color: hsl(120, 70%, 30%);
	}
	/* Add .note::before { content: "Note"; } for autogen label,
	   or use class="marker" to mark up the label in source. */

	details.note > summary {
		display: block;
		color: hsl(120, 70%, 30%);
	}
	details.note[open] > summary {
		border-bottom: 1px silver solid;
	}

/** Assertion Box *************************************************************/
	/*  for assertions in algorithms */

	.assertion {
		border-color: #AAA;
		background: #EEE;
	}

/** Advisement Box ************************************************************/
	/*  for attention-grabbing normative statements */

	.advisement {
		border-color: orange;
		border-style: none solid;
		background: #FFEECC;
	}
	strong.advisement {
		display: block;
		text-align: center;
	}
	.advisement > .marker {
		color: #B35F00;
	}

/** Spec Obsoletion Notice ****************************************************/
	/* obnoxious obsoletion notice for older/abandoned specs. */

	details {
		display: block;
	}
	summary {
		font-weight: bolder;
	}

	.annoying-warning:not(details),
	details.annoying-warning:not([open]) > summary,
	details.annoying-warning[open] {
		background: #fdd;
		color: red;
		font-weight: bold;
		padding: .75em 1em;
		border: thick red;
		border-style: solid;
		border-radius: 1em;
	}
	.annoying-warning :last-child {
		margin-bottom: 0;
	}

@media not print {
	details.annoying-warning[open] {
		position: fixed;
		left: 1em;
		right: 1em;
		bottom: 1em;
		z-index: 1000;
	}
}

	details.annoying-warning:not([open]) > summary {
		text-align: center;
	}

/** Entity Definition Boxes ***************************************************/

	.def {
		padding: .5em 1em;
		background: #DEF;
		margin: 1.2em 0;
		border-left: 0.5em solid #8CCBF2;
	}

/******************************************************************************/
/*                                    Tables                                  */
/******************************************************************************/

	th, td {
		text-align: left;
		text-align: start;
	}

/** Property/Descriptor Definition Tables *************************************/

	table.def {
		/* inherits .def box styling, see above */
		width: 100%;
		border-spacing: 0;
	}

	table.def td,
	table.def th {
		padding: 0.5em;
		vertical-align: baseline;
		border-bottom: 1px solid #bbd7e9;
	}

	table.def > tbody > tr:last-child th,
	table.def > tbody > tr:last-child td {
		border-bottom: 0;
	}

	table.def th {
		font-style: italic;
		font-weight: normal;
		padding-left: 1em;
		width: 3em;
	}

	/* For when values are extra-complex and need formatting for readability */
	table td.pre {
		white-space: pre-wrap;
	}

	/* A footnote at the bottom of a def table */
	table.def           td.footnote {
		padding-top: 0.6em;
	}
	table.def           td.footnote::before {
		content: " ";
		display: block;
		height: 0.6em;
		width: 4em;
		border-top: thin solid;
	}

/** Data tables (and properly marked-up index tables) *************************/
	/*
		 <table class="data"> highlights structural relationships in a table
		 when correct markup is used (e.g. thead/tbody, th vs. td, scope attribute)

		 Use class="complex data" for particularly complicated tables --
		 (This will draw more lines: busier, but clearer.)

		 Use class="long" on table cells with paragraph-like contents
		 (This will adjust text alignment accordingly.)
		 Alternately use class="longlastcol" on tables, to have the last column assume "long".
	*/

	table {
		word-wrap: normal;
		overflow-wrap: normal;
		hyphens: manual;
	}

	table.data,
	table.index {
		margin: 1em auto;
		border-collapse: collapse;
		border: hidden;
		width: 100%;
	}
	table.data caption,
	table.index caption {
		max-width: 50em;
		margin: 0 auto 1em;
	}

	table.data td,  table.data th,
	table.index td, table.index th {
		padding: 0.5em 1em;
		border-width: 1px;
		border-color: silver;
		border-top-style: solid;
	}

	table.data thead td:empty {
		padding: 0;
		border: 0;
	}

	table.data  thead,
	table.index thead,
	table.data  tbody,
	table.index tbody {
		border-bottom: 2px solid;
	}

	table.data colgroup,
	table.index colgroup {
		border-left: 2px solid;
	}

	table.data  tbody th:first-child,
	table.index tbody th:first-child  {
		border-right: 2px solid;
		border-top: 1px solid silver;
		padding-right: 1em;
	}

	table.data th[colspan],
	table.data td[colspan] {
		text-align: center;
	}

	table.complex.data th,
	table.complex.data td {
		border: 1px solid silver;
		text-align: center;
	}

	table.data.longlastcol td:last-child,
	table.data td.long {
	 vertical-align: baseline;
	 text-align: left;
	}

	table.data img {
		vertical-align: middle;
	}


/*
Alternate table alignment rules

	table.data,
	table.index {
		text-align: center;
	}

	table.data  thead th[scope="row"],
	table.index thead th[scope="row"] {
		text-align: right;
	}

	table.data  tbody th:first-child,
	table.index tbody th:first-child  {
		text-align: right;
	}

Possible extra rowspan handling

	table.data  tbody th[rowspan]:not([rowspan='1']),
	table.index tbody th[rowspan]:not([rowspan='1']),
	table.data  tbody td[rowspan]:not([rowspan='1']),
	table.index tbody td[rowspan]:not([rowspan='1']) {
		border-left: 1px solid silver;
	}

	table.data  tbody th[rowspan]:first-child,
	table.index tbody th[rowspan]:first-child,
	table.data  tbody td[rowspan]:first-child,
	table.index tbody td[rowspan]:first-child{
		border-left: 0;
		border-right: 1px solid silver;
	}
*/

/******************************************************************************/
/*                                  Indices                                   */
/******************************************************************************/


/** Table of Contents *********************************************************/

	.toc a {
		/* More spacing; use padding to make it part of the click target. */
		padding-top: 0.1rem;
		/* Larger, more consistently-sized click target */
		display: block;
		/* Reverse color scheme */
		color: black;
		border-color: #3980B5;
		border-bottom-width: 3px !important;
		margin-bottom: 0px !important;
	}
	.toc a:visited {
		border-color: #054572;
	}
	.toc a:not(:focus):not(:hover) {
		/* Allow colors to cascade through from link styling */
		border-bottom-color: transparent;
	}

	.toc, .toc ol, .toc ul, .toc li {
		list-style: none; /* Numbers must be inlined into source */
		/* because generated content isn't search/selectable and markers can't do multilevel yet */
		margin:  0;
		padding: 0;
		line-height: 1.1rem; /* consistent spacing */
	}

	/* ToC not indented until third level, but font style & margins show hierarchy */
	.toc > li             { font-weight: bold;   }
	.toc > li li          { font-weight: normal; }
	.toc > li li li       { font-size:   95%;    }
	.toc > li li li li    { font-size:   90%;    }
	.toc > li li li li li { font-size:   85%;    }

	.toc > li             { margin: 1.5rem 0;    }
	.toc > li li          { margin: 0.3rem 0;    }
	.toc > li li li       { margin-left: 2rem;   }

	/* Section numbers in a column of their own */
	.toc .secno {
		float: left;
		width: 4rem;
		white-space: nowrap;
	}
	.toc > li li li li .secno {
		font-size: 85%;
	}
	.toc > li li li li li .secno {
		font-size: 100%;
	}

	:not(li) > .toc              { margin-left:  5rem; }
	.toc .secno                  { margin-left: -5rem; }
	.toc > li li li .secno       { margin-left: -7rem; }
	.toc > li li li li .secno    { margin-left: -9rem; }
	.toc > li li li li li .secno { margin-left: -11rem; }

	/* Tighten up indentation in narrow ToCs */
	@media (max-width: 30em) {
		:not(li) > .toc              { margin-left:  4rem; }
		.toc .secno                  { margin-left: -4rem; }
		.toc > li li li              { margin-left:  1rem; }
		.toc > li li li .secno       { margin-left: -5rem; }
		.toc > li li li li .secno    { margin-left: -6rem; }
		.toc > li li li li li .secno { margin-left: -7rem; }
	}
	@media screen and (min-width: 78em) {
		body:not(.toc-inline) :not(li) > .toc              { margin-left:  4rem; }
		body:not(.toc-inline) .toc .secno                  { margin-left: -4rem; }
		body:not(.toc-inline) .toc > li li li              { margin-left:  1rem; }
		body:not(.toc-inline) .toc > li li li .secno       { margin-left: -5rem; }
		body:not(.toc-inline) .toc > li li li li .secno    { margin-left: -6rem; }
		body:not(.toc-inline) .toc > li li li li li .secno { margin-left: -7rem; }
	}
	body.toc-sidebar #toc :not(li) > .toc              { margin-left:  4rem; }
	body.toc-sidebar #toc .toc .secno                  { margin-left: -4rem; }
	body.toc-sidebar #toc .toc > li li li              { margin-left:  1rem; }
	body.toc-sidebar #toc .toc > li li li .secno       { margin-left: -5rem; }
	body.toc-sidebar #toc .toc > li li li li .secno    { margin-left: -6rem; }
	body.toc-sidebar #toc .toc > li li li li li .secno { margin-left: -7rem; }

	.toc li {
		clear: both;
	}


/** Index *********************************************************************/

	/* Index Lists: Layout */
	ul.index       { margin-left: 0; columns: 15em; text-indent: 1em hanging; }
	ul.index li    { margin-left: 0; list-style: none; break-inside: avoid; }
	ul.index li li { margin-left: 1em }
	ul.index dl    { margin-top: 0; }
	ul.index dt    { margin: .2em 0 .2em 20px;}
	ul.index dd    { margin: .2em 0 .2em 40px;}
	/* Index Lists: Typography */
	ul.index ul,
	ul.index dl { font-size: smaller; }
	@media not print {
		ul.index li span {
			white-space: nowrap;
			color: transparent; }
		ul.index li a:hover + span,
		ul.index li a:focus + span {
			color: #707070;
		}
	}

/** Index Tables *****************************************************/
	/* See also the data table styling section, which this effectively subclasses */

	table.index {
		font-size: small;
		border-collapse: collapse;
		border-spacing: 0;
		text-align: left;
		margin: 1em 0;
	}

	table.index td,
	table.index th {
		padding: 0.4em;
	}

	table.index tr:hover td:not([rowspan]),
	table.index tr:hover th:not([rowspan]) {
		background: #f7f8f9;
	}

	/* The link in the first column in the property table (formerly a TD) */
	table.index th:first-child a {
		font-weight: bold;
	}

/******************************************************************************/
/*                                    Print                                   */
/******************************************************************************/

	@media print {
		/* Pages have their own margins. */
		html {
			margin: 0;
		}
		/* Serif for print. */
		body {
			font-family: serif;
		}
	}
	@page {
		margin: 1.5cm 1.1cm;
	}

/******************************************************************************/
/*                                    Legacy                                  */
/******************************************************************************/

	/* This rule is inherited from past style sheets. No idea what it's for. */
	.hide { display: none }



/******************************************************************************/
/*                             Overflow Control                               */
/******************************************************************************/

	.figure .caption, .sidefigure .caption, figcaption {
		/* in case figure is overlarge, limit caption to 50em */
		max-width: 50rem;
		margin-left: auto;
		margin-right: auto;
	}
	.overlarge > table {
		/* limit preferred width of table */
		max-width: 50em;
		margin-left: auto;
		margin-right: auto;
	}

	@media (min-width: 55em) {
		.overlarge {
			margin-left: calc(13px + 26.5rem - 50vw);
			margin-right: calc(13px + 26.5rem - 50vw);
			max-width: none;
		}
	}
	@media screen and (min-width: 78em) {
		body:not(.toc-inline) .overlarge {
			/* 30.5em body padding 50em content area */
			margin-left: calc(40em - 50vw) !important;
			margin-right: calc(40em - 50vw) !important;
		}
	}
	@media screen and (min-width: 90em) {
		body:not(.toc-inline) .overlarge {
			/* 4em html margin 30.5em body padding 50em content area */
			margin-left: 0 !important;
			margin-right: calc(84.5em - 100vw) !important;
		}
	}

	@media not print {
		.overlarge {
			overflow-x: auto;
			/* See Lea Verou's explanation background-attachment:
			 * http://lea.verou.me/2012/04/background-attachment-local/
			 *
			background: top left  / 4em 100% linear-gradient(to right,  #ffffff, rgba(255, 255, 255, 0)) local,
			            top right / 4em 100% linear-gradient(to left, #ffffff, rgba(255, 255, 255, 0)) local,
			            top left  / 1em 100% linear-gradient(to right,  #c3c3c5, rgba(195, 195, 197, 0)) scroll,
			            top right / 1em 100% linear-gradient(to left, #c3c3c5, rgba(195, 195, 197, 0)) scroll,
			            white;
			background-repeat: no-repeat;
			*/
		}
	}
</style>
<style type="text/css">
    table, th, td {
      border: 1px solid black;
      border-collapse: collapse;
      vertical-align: top;
    }
    th, td {
      border-left: none;
      border-right: none;
      padding: 0px 10px;
    }
    th {
      text-align: center;
    }
  </style>
  <meta content="Bikeshed version a6f3456a9bb025e0d80ba8bd36ecc4cd6461925d" name="generator">
  <link href="http://wg21.link/p0947r1" rel="canonical">
<style>/* style-md-lists */

/* This is a weird hack for me not yet following the commonmark spec
   regarding paragraph and lists. */
[data-md] > :first-child {
    margin-top: 0;
}
[data-md] > :last-child {
    margin-bottom: 0;
}</style>
<style>/* style-selflinks */

.heading, .issue, .note, .example, li, dt {
    position: relative;
}
a.self-link {
    position: absolute;
    top: 0;
    left: calc(-1 * (3.5rem - 26px));
    width: calc(3.5rem - 26px);
    height: 2em;
    text-align: center;
    border: none;
    transition: opacity .2s;
    opacity: .5;
}
a.self-link:hover {
    opacity: 1;
}
.heading > a.self-link {
    font-size: 83%;
}
li > a.self-link {
    left: calc(-1 * (3.5rem - 26px) - 2em);
}
dfn > a.self-link {
    top: auto;
    left: auto;
    opacity: 0;
    width: 1.5em;
    height: 1.5em;
    background: gray;
    color: white;
    font-style: normal;
    transition: opacity .2s, background-color .2s, color .2s;
}
dfn:hover > a.self-link {
    opacity: 1;
}
dfn > a.self-link:hover {
    color: black;
}

a.self-link::before            { content: "¶"; }
.heading > a.self-link::before { content: "§"; }
dfn > a.self-link::before      { content: "#"; }</style>
<style>/* style-counters */

body {
    counter-reset: example figure issue;
}
.issue {
    counter-increment: issue;
}
.issue:not(.no-marker)::before {
    content: "Issue " counter(issue);
}

.example {
    counter-increment: example;
}
.example:not(.no-marker)::before {
    content: "Example " counter(example);
}
.invalid.example:not(.no-marker)::before,
.illegal.example:not(.no-marker)::before {
    content: "Invalid Example" counter(example);
}

figcaption {
    counter-increment: figure;
}
figcaption:not(.no-marker)::before {
    content: "Figure " counter(figure) " ";
}</style>
<style>/* style-autolinks */

.css.css, .property.property, .descriptor.descriptor {
    color: #005a9c;
    font-size: inherit;
    font-family: inherit;
}
.css::before, .property::before, .descriptor::before {
    content: "‘";
}
.css::after, .property::after, .descriptor::after {
    content: "’";
}
.property, .descriptor {
    /* Don't wrap property and descriptor names */
    white-space: nowrap;
}
.type { /* CSS value <type> */
    font-style: italic;
}
pre .property::before, pre .property::after {
    content: "";
}
[data-link-type="property"]::before,
[data-link-type="propdesc"]::before,
[data-link-type="descriptor"]::before,
[data-link-type="value"]::before,
[data-link-type="function"]::before,
[data-link-type="at-rule"]::before,
[data-link-type="selector"]::before,
[data-link-type="maybe"]::before {
    content: "‘";
}
[data-link-type="property"]::after,
[data-link-type="propdesc"]::after,
[data-link-type="descriptor"]::after,
[data-link-type="value"]::after,
[data-link-type="function"]::after,
[data-link-type="at-rule"]::after,
[data-link-type="selector"]::after,
[data-link-type="maybe"]::after {
    content: "’";
}

[data-link-type].production::before,
[data-link-type].production::after,
.prod [data-link-type]::before,
.prod [data-link-type]::after {
    content: "";
}

[data-link-type=element],
[data-link-type=element-attr] {
    font-family: Menlo, Consolas, "DejaVu Sans Mono", monospace;
    font-size: .9em;
}
[data-link-type=element]::before { content: "<" }
[data-link-type=element]::after  { content: ">" }

[data-link-type=biblio] {
    white-space: pre;
}</style>
<style>/* style-railroad */
svg.railroad-diagram{background-color:hsl(30,20%,95%);}svg.railroad-diagram path{stroke-width:3px;stroke:black;fill:rgba(0,0,0,0);}svg.railroad-diagram text{font:bold 14px monospace;text-anchor:middle;}svg.railroad-diagram text.label{text-anchor:start;}svg.railroad-diagram text.comment{font:italic 12px monospace;}svg.railroad-diagram rect{stroke-width:3px;stroke:black;fill:hsl(120,100%,90%);}</style>
<style>/* style-syntax-highlighting */

.highlight:not(.idl) { background: hsl(24, 20%, 95%); }
code.highlight { padding: .1em; border-radius: .3em; }
pre.highlight, pre > code.highlight { display: block; padding: 1em; margin: .5em 0; overflow: auto; border-radius: 0; }
.highlight .c { color: #708090 } /* Comment */
.highlight .k { color: #990055 } /* Keyword */
.highlight .l { color: #000000 } /* Literal */
.highlight .n { color: #0077aa } /* Name */
.highlight .o { color: #999999 } /* Operator */
.highlight .p { color: #999999 } /* Punctuation */
.highlight .cm { color: #708090 } /* Comment.Multiline */
.highlight .cp { color: #708090 } /* Comment.Preproc */
.highlight .c1 { color: #708090 } /* Comment.Single */
.highlight .cs { color: #708090 } /* Comment.Special */
.highlight .kc { color: #990055 } /* Keyword.Constant */
.highlight .kd { color: #990055 } /* Keyword.Declaration */
.highlight .kn { color: #990055 } /* Keyword.Namespace */
.highlight .kp { color: #990055 } /* Keyword.Pseudo */
.highlight .kr { color: #990055 } /* Keyword.Reserved */
.highlight .kt { color: #990055 } /* Keyword.Type */
.highlight .ld { color: #000000 } /* Literal.Date */
.highlight .m { color: #000000 } /* Literal.Number */
.highlight .s { color: #a67f59 } /* Literal.String */
.highlight .na { color: #0077aa } /* Name.Attribute */
.highlight .nc { color: #0077aa } /* Name.Class */
.highlight .no { color: #0077aa } /* Name.Constant */
.highlight .nd { color: #0077aa } /* Name.Decorator */
.highlight .ni { color: #0077aa } /* Name.Entity */
.highlight .ne { color: #0077aa } /* Name.Exception */
.highlight .nf { color: #0077aa } /* Name.Function */
.highlight .nl { color: #0077aa } /* Name.Label */
.highlight .nn { color: #0077aa } /* Name.Namespace */
.highlight .py { color: #0077aa } /* Name.Property */
.highlight .nt { color: #669900 } /* Name.Tag */
.highlight .nv { color: #222222 } /* Name.Variable */
.highlight .ow { color: #999999 } /* Operator.Word */
.highlight .mb { color: #000000 } /* Literal.Number.Bin */
.highlight .mf { color: #000000 } /* Literal.Number.Float */
.highlight .mh { color: #000000 } /* Literal.Number.Hex */
.highlight .mi { color: #000000 } /* Literal.Number.Integer */
.highlight .mo { color: #000000 } /* Literal.Number.Oct */
.highlight .sb { color: #a67f59 } /* Literal.String.Backtick */
.highlight .sc { color: #a67f59 } /* Literal.String.Char */
.highlight .sd { color: #a67f59 } /* Literal.String.Doc */
.highlight .s2 { color: #a67f59 } /* Literal.String.Double */
.highlight .se { color: #a67f59 } /* Literal.String.Escape */
.highlight .sh { color: #a67f59 } /* Literal.String.Heredoc */
.highlight .si { color: #a67f59 } /* Literal.String.Interpol */
.highlight .sx { color: #a67f59 } /* Literal.String.Other */
.highlight .sr { color: #a67f59 } /* Literal.String.Regex */
.highlight .s1 { color: #a67f59 } /* Literal.String.Single */
.highlight .ss { color: #a67f59 } /* Literal.String.Symbol */
.highlight .vc { color: #0077aa } /* Name.Variable.Class */
.highlight .vg { color: #0077aa } /* Name.Variable.Global */
.highlight .vi { color: #0077aa } /* Name.Variable.Instance */
.highlight .il { color: #000000 } /* Literal.Number.Integer.Long */
</style>
 <body class="h-entry">
  <div class="head">
   <p data-fill-with="logo"></p>
   <h1 class="p-name no-ref" id="title">P0947R1<br>Another take on Modules</h1>
   <h2 class="no-num no-toc no-ref heading settled" id="subtitle"><span class="content">Published Proposal, <time class="dt-updated" datetime="2018-03-06">6 March 2018</time></span></h2>
   <div data-fill-with="spec-metadata">
    <dl>
     <dt>This version:
     <dd><a class="u-url" href="http://wg21.link/p0947r1">http://wg21.link/p0947r1</a>
     <dt>Author:
     <dd>
      <dd class="editor p-author h-card vcard"><a class="p-name fn u-email email" href="mailto:richard@metafoo.co.uk">Richard Smith</a> (<span class="p-org org">Google</span>)
     <dt>Audience:
     <dd>EWG
     <dt>Project:
     <dd>ISO JTC1/SC22/WG21: Programming Language C++
    </dl>
   </div>
   <div data-fill-with="warning"></div>
   <hr title="Separator for header">
  </div>
  <div class="p-summary" data-fill-with="abstract">
   <h2 class="no-num no-toc no-ref heading settled" id="abstract"><span class="content">Abstract</span></h2>
   <p>This paper discusses a set of extensions to C++ to support build scalability and library encapsulation.</p>
  </div>
  <nav data-fill-with="table-of-contents" id="toc">
   <h2 class="no-num no-toc no-ref" id="contents">Table of Contents</h2>
   <ol class="toc" role="directory">
    <li><a href="#history"><span class="secno">1</span> <span class="content">Revision history</span></a>
    <li>
     <a href="#overview"><span class="secno">2</span> <span class="content">Overview</span></a>
     <ol class="toc">
      <li>
       <a href="#why"><span class="secno">2.1</span> <span class="content">Background and motivation</span></a>
       <ol class="toc">
        <li><a href="#why-not-modules-ts"><span class="secno">2.1.1</span> <span class="content">Why not the Modules TS?</span></a>
       </ol>
      <li><a href="#goals"><span class="secno">2.2</span> <span class="content">Design goals</span></a>
      <li><a href="#principles"><span class="secno">2.3</span> <span class="content">Design principles</span></a>
     </ol>
    <li>
     <a href="#basics"><span class="secno">3</span> <span class="content">Basics</span></a>
     <ol class="toc">
      <li>
       <a href="#modules"><span class="secno">3.1</span> <span class="content">Modules</span></a>
       <ol class="toc">
        <li><a href="#module-ownership"><span class="secno">3.1.1</span> <span class="content">Module ownership</span></a>
       </ol>
      <li>
       <a href="#tu-structure"><span class="secno">3.2</span> <span class="content">Translation unit structure</span></a>
       <ol class="toc">
        <li><a href="#module-decl"><span class="secno">3.2.1</span> <span class="content">The <em>module-declaration</em></span></a>
        <li><a href="#import-decl"><span class="secno">3.2.2</span> <span class="content"><em>import-declaration</em>s</span></a>
       </ol>
      <li><a href="#partitions"><span class="secno">3.3</span> <span class="content">Module partitions</span></a>
     </ol>
    <li>
     <a href="#imports"><span class="secno">4</span> <span class="content">Imports</span></a>
     <ol class="toc">
      <li><a href="#import-semantics"><span class="secno">4.1</span> <span class="content">Import semantics</span></a>
      <li>
       <a href="#import-visibility"><span class="secno">4.2</span> <span class="content">Transitive visibility of imports</span></a>
       <ol class="toc">
        <li><a href="#private-imports"><span class="secno">4.2.1</span> <span class="content">Private imports</span></a>
        <li><a href="#exported-imports"><span class="secno">4.2.2</span> <span class="content">Exported imports</span></a>
        <li><a href="#public-imports"><span class="secno">4.2.3</span> <span class="content">Public imports</span></a>
       </ol>
      <li><a href="#import-and-cpp"><span class="secno">4.3</span> <span class="content">Preprocessor impact</span></a>
     </ol>
    <li>
     <a href="#exports"><span class="secno">5</span> <span class="content">Exports</span></a>
     <ol class="toc">
      <li><a href="#name-export"><span class="secno">5.1</span> <span class="content">Name export</span></a>
      <li><a href="#macro-export"><span class="secno">5.2</span> <span class="content">Macro export</span></a>
     </ol>
    <li>
     <a href="#legacy-headers"><span class="secno">6</span> <span class="content">Legacy headers</span></a>
     <ol class="toc">
      <li><a href="#legacy-header-units"><span class="secno">6.1</span> <span class="content">Legacy header units</span></a>
      <li><a href="#include-translation"><span class="secno">6.2</span> <span class="content"><code class="highlight"><span class="cp">#include</span></code> translation</span></a>
      <li><a href="#legacy-header-compilation"><span class="secno">6.3</span> <span class="content">Compilation model</span></a>
     </ol>
    <li>
     <a href="#low-level"><span class="secno">7</span> <span class="content">Low-level design details</span></a>
     <ol class="toc">
      <li><a href="#template-lookup"><span class="secno">7.1</span> <span class="content">Templates and two-phase name lookup</span></a>
     </ol>
    <li><a href="#ack"><span class="secno">8</span> <span class="content">Acknowledgements</span></a>
    <li>
     <a href="#index"><span class="secno"></span> <span class="content">Index</span></a>
     <ol class="toc">
      <li><a href="#index-defined-here"><span class="secno"></span> <span class="content">Terms defined by this specification</span></a>
     </ol>
    <li>
     <a href="#references"><span class="secno"></span> <span class="content">References</span></a>
     <ol class="toc">
      <li><a href="#informative"><span class="secno"></span> <span class="content">Informative References</span></a>
     </ol>
   </ol>
  </nav>
  <main>
   <h2 class="heading settled" data-level="1" id="history"><span class="secno">1. </span><span class="content">Revision history</span><a class="self-link" href="#history"></a></h2>
   <p>Changes since R0:</p>
   <ul>
    <li data-md="">
     <p><code class="highlight"><span class="k">export</span> <span class="n">import</span></code> no longer re-exports macros, and <code class="highlight"><span class="cp">#export</span></code> is now orthogonal functionality</p>
   </ul>
   <h2 class="heading settled" data-level="2" id="overview"><span class="secno">2. </span><span class="content">Overview</span><a class="self-link" href="#overview"></a></h2>
   <h3 class="heading settled" data-level="2.1" id="why"><span class="secno">2.1. </span><span class="content">Background and motivation</span><a class="self-link" href="#why"></a></h3>
   <p>C++ is used for many of the world’s largest software systems. But as systems scale upwards, a number of problems emerge that C++ does not provide adequate tools to tackle. We particularly note these problems:</p>
   <ul>
    <li data-md="">
     <p>Distinct components cannot be adequately isolated from one another; implementation details leak across component boundaries, and users are tempted to break encapsulation by redeclaring entities owned by other components.</p>
    <li data-md="">
     <p>Code does not have hermetic semantics: the meaning of an interface can depend on declarations and macros exposed by the user of that interface prior to its inclusion.</p>
    <li data-md="">
     <p>Build performance grows near-quadratically, because in practice source files transitively depend upon and <code class="highlight"><span class="cp">#include</span></code> an approximately constant fraction of all components' interfaces.</p>
   </ul>
   <p>The commonality between these problems is that the C++ model for providing interfaces is by redeclaring those interfaces in every source file, typically by textual inclusion.</p>
   <p>These problems have been considered by several groups and individuals before; notably, the C++ Modules Technical Specification (<a data-link-type="biblio" href="#biblio-n4720">[N4720]</a>) provides one possible direction to resolve these issues. The design in this paper is based on a different prioritization of goals than those of the Modules TS, resulting in different choices being made in various key areas, but we follow the Modules TS in all cases where our priorities do not necessitate a different decision. We are grateful to all who have contributed to the Modules TS for providing a framework of terminology and ideas for us to draw from within this proposal.</p>
   <h4 class="heading settled" data-level="2.1.1" id="why-not-modules-ts"><span class="secno">2.1.1. </span><span class="content">Why not the Modules TS?</span><a class="self-link" href="#why-not-modules-ts"></a></h4>
   <p>A number of prior papers have raised design concerns with the Modules TS. We believe these concerns largely stem from the design of the Modules TS being based on a different prioritization of goals than those of the parties raising the concerns. However, we believe that it is possible to address nearly all of the raised concerns without compromising the fundamental goals of the modules effort, and this proposal seeks to do so. Specifically, we would draw the reader’s attention to:</p>
   <ul>
    <li data-md="">
     <p><a data-link-type="biblio" href="#biblio-p0273r0">[P0273R0]</a> (by the author of this paper and others) raises a collection of concerns; we address all concerns therein other than "Module names as strings", to which the committee has expressed objections.</p>
    <li data-md="">
     <p><a data-link-type="biblio" href="#biblio-p0678r0">[P0678R0]</a> describes Bloomberg business requirements for modules. We believe this proposal addresses the described requirements, which are very similar to our own, as we provide an additive, interoperable approach to modules that provides an incremental path to adoption.</p>
    <li data-md="">
     <p><a data-link-type="biblio" href="#biblio-p0713r0">[P0713R0]</a>, <a data-link-type="biblio" href="#biblio-p0774r0">[P0774R0]</a> raise the concern that a human reader should be able to identify whether a source file is a module unit by inspecting its initial contents, although they describe different solutions to the problem. This proposal addresses that concern: the <em>module-declaration</em> is always at the start of the translation unit if present.</p>
    <li data-md="">
     <p><a data-link-type="biblio" href="#biblio-p0775r0">[P0775R0]</a> describes the problem of permitting the interface of a module to be split across multiple source files. This proposal introduces module partitions to solve that problem and others.</p>
    <li data-md="">
     <p><a data-link-type="biblio" href="#biblio-p0795r0">[P0795R0]</a> describes compatibility problems caused by the introduction of the <code class="highlight"><span class="n">module</span></code> keyword. Further research has indicated that the identifiers <code class="highlight"><span class="n">module</span></code> and <code class="highlight"><span class="n">import</span></code> are both in widespread usage in multiple codebases, and in some cases are part of immutable APIs. This proposal avoids breaking such code by treating these identifiers as context-sensitive keywords. This is made possible by requiring a specific ordering of the <em>module-declaration</em> and <em>import-declaration</em>s within a translation unit.</p>
    <li data-md="">
     <p><a data-link-type="biblio" href="#biblio-p0841r0">[P0841R0]</a> describes a set of concrete problems that would prevent the Modules TS from being used as-is by Apple. We believe this proposal resolves all the problems described in that paper; the modules proposal we describe here provides as a subset a system very similar to the Clang header modules system currently in use by Apple.</p>
    <li data-md="">
     <p><a data-link-type="biblio" href="#biblio-n4697">[N4697]</a> contains the accumulated ballot comments on the Modules TS, reflecting many of the design concerns raised above, which we believe are well addressed by this proposal.</p>
   </ul>
   <h3 class="heading settled" data-level="2.2" id="goals"><span class="secno">2.2. </span><span class="content">Design goals</span><a class="self-link" href="#goals"></a></h3>
   <p>In order to support scalable software development, this paper aims to do the following:</p>
   <ul>
    <li data-md="">
     <p>Provide a mechanism to allow the interface of a translation unit to be controlled and exposed to other translation units.</p>
    <li data-md="">
     <p>Ensure that natural implementation strategies for importation of such an interface have a compile-time cost that is linear in the size of the interface that is used (rather than linear in the size of the transitive interface that is exposed, as is the case in current C++).</p>
    <li data-md="">
     <p>Ensure interfaces are hermetic: the exported interface should not depend in any way on earlier-declared names and macros.</p>
    <li data-md="">
     <p>Ensure components are encapsulated: prevent code outside a component from "reaching into" that component and accessing its internals.</p>
    <li data-md="">
     <p>Allow components to control the interface they expose to other components, and in particular provide clear boundaries around which parts of the implementation are exposed to client code and which are not.</p>
    <li data-md="">
     <p>Support incremental adoption of the features within this proposal, where it is expected that in some cases it will take decades for all clients of a component to transition to the new features, and the software must remain maintainable in the interim.</p>
    <li data-md="">
     <p>Support continued use of legacy code that cannot ever reasonably transition to these features, without resorting to the myriad problems of textual inclusion.</p>
    <li data-md="">
     <p>Arrange the language features to facilitate basic understanding of C++ code by tools that are not compilers.</p>
    <li data-md="">
     <p>Do not change the fundamentals of C++, except as necessary to support the above goals.</p>
   </ul>
   <h3 class="heading settled" data-level="2.3" id="principles"><span class="secno">2.3. </span><span class="content">Design principles</span><a class="self-link" href="#principles"></a></h3>
   <p>The extensions described in this paper aim to conform to these design principles:</p>
   <ul>
    <li data-md="">
     <p><em>Be consistent and general</em>. New language features should
integrate into the existing language, and should consistently support all
facets of the existing language equally. This proposal directly supports exporting
and importing all constructs that participate in C++ interfaces, including macros.</p>
    <li data-md="">
     <p><em>Be orthogonal</em>. Distinct concepts and functionality should not be unnecessarily coupled,
and programmers should be given the flexibility to choose when to use features together.
This proposal does not couple modue boundaries to translation unit
boundaries, instead permitting modules to span as many few or many translation units
as is suitable for the project. Likewise, whether a translation unit provides part of the
interface of a module is not coupled to whether a translation unit is importable, permitting
importation of implementation details within a module.</p>
    <li data-md="">
     <p><em>Old code and new code are both critical</em>. The success of C++ is in part
due to transparently supporting a huge subset of existing C code, and
allowing existing code to immediately take advantage of new features. To be adopted,
any language extension that aims to fundamentally change how we manage,
structure, and build our source code must support existing
code as well as it supports new code. This proposal provides direct support
for existing code by allowing header files to interoperate directly with the
introduced import mechanism.</p>
    <li data-md="">
     <p><em>You don’t pay for what you don’t use</em>. This proposal aims to adopt this principle
at several levels. When importing an interface (including a legacy header unit), the
cost grows with the portion of the interface used, not with the transitive size of the
interface. Only names and macros from imported translation units are made visible,
mitigating the risk of accidental name collision.</p>
   </ul>
   <h2 class="heading settled" data-level="3" id="basics"><span class="secno">3. </span><span class="content">Basics</span><a class="self-link" href="#basics"></a></h2>
   <h3 class="heading settled" data-level="3.1" id="modules"><span class="secno">3.1. </span><span class="content">Modules</span><a class="self-link" href="#modules"></a></h3>
   <p>This proposal introduces the notion of a <dfn data-dfn-type="dfn" data-noexport="" id="module">module<a class="self-link" href="#module"></a></dfn>, which represents an encapsulated component within a program. A module comprises a collection of translation units of four kinds (collectively known as <dfn data-dfn-type="dfn" data-noexport="" id="module-unit">module unit<a class="self-link" href="#module-unit"></a></dfn>s):</p>
   <ul>
    <li data-md="">
     <p>The <dfn data-dfn-type="dfn" data-noexport="" id="interface-unit">interface unit<a class="self-link" href="#interface-unit"></a></dfn> of a module is a translation unit defining the external interface of the module. They are introduced with the syntax<br> <code class="highlight"><span class="k">export</span> <span class="n">module</span></code> <em>module-name</em> <code class="highlight"><span class="p">;</span></code></p>
    <li data-md="">
     <p>A <dfn data-dfn-type="dfn" data-noexport="" id="module-partition">module partition<a class="self-link" href="#module-partition"></a></dfn> is a translation unit that supports semantic import within the same module. Module partitions may be re-exported from the primary interface unit, but need not be. They are introduced with the syntax<br> <code class="highlight"><span class="k">export</span> <span class="n">module</span></code> <em>module-name</em> <code class="highlight"><span class="o">:</span></code> <em>partition-name</em> <code class="highlight"><span class="p">;</span></code><br> See <a href="#partitions">§3.3 Module partitions</a>.</p>
    <li data-md="">
     <p>An <dfn data-dfn-type="dfn" data-noexport="" id="implementation-unit">implementation unit<a class="self-link" href="#implementation-unit"></a></dfn> of a module is a translation unit providing implementation details within the semantic scope of the module. They are introduced with the syntax<br> <code class="highlight"><span class="n">module</span></code> <em>module-name</em> <code class="highlight"><span class="p">;</span></code></p>
    <li data-md="">
     <p>A <dfn data-dfn-type="dfn" data-noexport="" id="legacy-header-unit">legacy header unit<a class="self-link" href="#legacy-header-unit"></a></dfn> of a module is a translation unit synthesized by the implementation to allow import of a legacy header file. See <a href="#legacy-headers">§6 Legacy headers</a>.</p>
   </ul>
   <p>A module that contains any translation units that are not legacy header units must contain exactly one interface unit. There are no other bounds on how many or few translation units it can contain.</p>
   <p>Each module depends on a set of other modules; the mechanism for specifying this set is implementation-defined. If a module imports a translation unit owned by a module on which it does not have a dependency, the program is ill-formed.</p>
   <div class="note" role="note">
     <strong>Rationale:</strong> 
    <p>Requiring module dependencies to be explicitly specified has many advantages:</p>
    <ul>
     <li data-md="">
      <p>It provides the build system the necessary information to link in all used modules, by producing a compilation error if such a build system dependency is missing.</p>
     <li data-md="">
      <p>It allows external enforcement of layering, by requiring layering in the module dependencies in the build system or another tool.</p>
     <li data-md="">
      <p>It allows external enforcement of visibility restrictions (for instance, if certain modules should only be used by a restricted set of other modules, the compiler can help enforce this constraint).</p>
    </ul>
    <p>A build tool can choose to compute the set of module dependencies by extracting them from the source code itself, if dependency constraints are not desired for the project.</p>
   </div>
   <h4 class="heading settled" data-level="3.1.1" id="module-ownership"><span class="secno">3.1.1. </span><span class="content">Module ownership</span><a class="self-link" href="#module-ownership"></a></h4>
   <p>Entities declared within a module are <em>owned</em> by that module. Declarations owned by distinct modules are distinct entities. The program is ill-formed (no diagnostic required) if two modules export conflicting declarations of the same name; non-exported declarations may coexist so long as a declaration of one such entity does not occur while another such entity is visible.</p>
   <p>As a special exception, some entities are never owned by a module even if declared within a module:</p>
   <ul>
    <li data-md="">
     <p>namespaces (namespace members may be owned, but namespace names never are)</p>
    <li data-md="">
     <p>the global replaceable allocation and deallocation functions</p>
    <li data-md="">
     <p>entities first declared within language linkage specifications (<code class="highlight"><span class="k">extern</span> <span class="s">"C"</span></code> and <code class="highlight"><span class="k">extern</span> <span class="s">"C++"</span></code>)</p>
   </ul>
   <div class="note" role="note">
     <strong>Rationale:</strong> 
    <p>Module ownership allows encapsulation of implementation details of modules, so that two translation units in a module can share names internally without risking collisions with other modules.</p>
    <p>However, namespaces are still the mechanism by which global uniqueness of names is ensured: names crossing module boundaries (those names that are exported) are still fundamentally a single global resource shared across the program, as we can expect that if a program has two conflicting definitions of a name, those two different meanings will eventually be needed in the same translation unit. Hence such situations are disallowed, so that poor namespace discipline can be caught and remedied early.</p>
   </div>
   <h3 class="heading settled" data-level="3.2" id="tu-structure"><span class="secno">3.2. </span><span class="content">Translation unit structure</span><a class="self-link" href="#tu-structure"></a></h3>
   <p>A module unit has the following structure:</p>
   <blockquote>
    <p><em>module-declaration</em><br> <br> <em>import-declaration</em><br> <em>import-declaration</em><br> …<br> <em>import-declaration</em><br> <br> <em>declaration</em><br> <em>declaration</em><br> ...<br> <em>declaration</em></p>
   </blockquote>
   <p>Note that the <em>module-declaration</em> appears first, and all <em>import-declaration</em>s appear before any other <em>declaration</em>s.</p>
   <p>A translation unit that is not a module unit has the same structure, with the leading <em>module-declaration</em> omitted.</p>
   <div class="note" role="note">
     <strong>Rationale:</strong> 
    <p>Requiring a specific order provides several advantages:</p>
    <ul>
     <li data-md="">
      <p>It enforces a convention that is near-universally considered to be good style.</p>
     <li data-md="">
      <p>It permits the dependency graph of a module to be quickly determined, without analysing the entire source file, and for the correspondence between source files and modules to likewise be quickly determined.</p>
     <li data-md="">
      <p>Requiring the module-declaration to be first ensures the owning module is known before the compiler performs steps that might depend upon it, such as opening output files and generating mangled names.</p>
    </ul>
   </div>
   <h4 class="heading settled" data-level="3.2.1" id="module-decl"><span class="secno">3.2.1. </span><span class="content">The <em>module-declaration</em></span><a class="self-link" href="#module-decl"></a></h4>
   <p>The general form of a <em>module-declaration</em> is:</p>
   <div class="railroad">
    <svg class="railroad-diagram" height="101" viewBox="0 0 916 101" width="916">
     <g transform="translate(.5 .5)">
      <path d="M 20 30 v 20 m 10 -20 v 20 m -10 -10 h 20.5"></path>
      <g>
       <path d="M40 40h0"></path>
       <path d="M284 40h0"></path>
       <path d="M40 40a10 10 0 0 0 10 -10v0a10 10 0 0 1 10 -10"></path>
       <g>
        <path d="M60 20h204"></path>
       </g>
       <path d="M264 20a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path>
       <path d="M40 40h20"></path>
       <g class="non-terminal">
        <path d="M60 40h0"></path>
        <path d="M264 40h0"></path>
        <rect height="22" width="204" x="60" y="29"></rect>
        <a href="">
         <text x="162" y="44">attribute-specifier-seq</text>
         <text x="162" y="44">attribute-specifier-seq</text>
        </a>
       </g>
       <path d="M264 40h20"></path>
      </g>
      <g>
       <path d="M284 40h0"></path>
       <path d="M392 40h0"></path>
       <path d="M284 40a10 10 0 0 0 10 -10v0a10 10 0 0 1 10 -10"></path>
       <g>
        <path d="M304 20h68"></path>
       </g>
       <path d="M372 20a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path>
       <path d="M284 40h20"></path>
       <g class="terminal">
        <path d="M304 40h0"></path>
        <path d="M372 40h0"></path>
        <rect height="22" rx="10" ry="10" width="68" x="304" y="29"></rect>
        <a href="">
         <text x="338" y="44">export</text>
         <text x="338" y="44">export</text>
        </a>
       </g>
       <path d="M372 40h20"></path>
      </g>
      <path d="M392 40h10"></path>
      <g class="terminal">
       <path d="M402 40h0"></path>
       <path d="M470 40h0"></path>
       <rect height="22" rx="10" ry="10" width="68" x="402" y="29"></rect>
       <a href="">
        <text x="436" y="44">module</text>
        <text x="436" y="44">module</text>
       </a>
      </g>
      <path d="M470 40h10"></path>
      <path d="M480 40h10"></path>
      <g>
       <path d="M490 40h0"></path>
       <path d="M610 40h0"></path>
       <path d="M490 40h10"></path>
       <g class="non-terminal">
        <path d="M500 40h0"></path>
        <path d="M600 40h0"></path>
        <rect height="22" width="100" x="500" y="29"></rect>
        <a href="">
         <text x="550" y="44">identifier</text>
         <text x="550" y="44">identifier</text>
        </a>
       </g>
       <path d="M600 40h10"></path>
       <path d="M500 40a10 10 0 0 0 -10 10v10a10 10 0 0 0 10 10"></path>
       <g class="terminal">
        <path d="M500 70h36"></path>
        <path d="M564 70h36"></path>
        <rect height="22" rx="10" ry="10" width="28" x="536" y="59"></rect>
        <a href="">
         <text x="550" y="74">.</text>
         <text x="550" y="74">.</text>
        </a>
       </g>
       <path d="M600 70a10 10 0 0 0 10 -10v-10a10 10 0 0 0 -10 -10"></path>
      </g>
      <path d="M610 40h10"></path>
      <g>
       <path d="M620 40h0"></path>
       <path d="M828 40h0"></path>
       <path d="M620 40a10 10 0 0 0 10 -10v0a10 10 0 0 1 10 -10"></path>
       <g>
        <path d="M640 20h168"></path>
       </g>
       <path d="M808 20a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path>
       <path d="M620 40h20"></path>
       <g>
        <path d="M640 40h0"></path>
        <path d="M808 40h0"></path>
        <g class="terminal">
         <path d="M640 40h0"></path>
         <path d="M668 40h0"></path>
         <rect height="22" rx="10" ry="10" width="28" x="640" y="29"></rect>
         <a href="">
          <text x="654" y="44">:</text>
          <text x="654" y="44">:</text>
         </a>
        </g>
        <path d="M668 40h10"></path>
        <path d="M678 40h10"></path>
        <g>
         <path d="M688 40h0"></path>
         <path d="M808 40h0"></path>
         <path d="M688 40h10"></path>
         <g class="non-terminal">
          <path d="M698 40h0"></path>
          <path d="M798 40h0"></path>
          <rect height="22" width="100" x="698" y="29"></rect>
          <a href="">
           <text x="748" y="44">identifier</text>
           <text x="748" y="44">identifier</text>
          </a>
         </g>
         <path d="M798 40h10"></path>
         <path d="M698 40a10 10 0 0 0 -10 10v10a10 10 0 0 0 10 10"></path>
         <g class="terminal">
          <path d="M698 70h36"></path>
          <path d="M762 70h36"></path>
          <rect height="22" rx="10" ry="10" width="28" x="734" y="59"></rect>
          <a href="">
           <text x="748" y="74">.</text>
           <text x="748" y="74">.</text>
          </a>
         </g>
         <path d="M798 70a10 10 0 0 0 10 -10v-10a10 10 0 0 0 -10 -10"></path>
        </g>
       </g>
       <path d="M808 40h20"></path>
      </g>
      <path d="M828 40h10"></path>
      <g class="terminal">
       <path d="M838 40h0"></path>
       <path d="M866 40h0"></path>
       <rect height="22" rx="10" ry="10" width="28" x="838" y="29"></rect>
       <a href="">
        <text x="852" y="44">;</text>
        <text x="852" y="44">;</text>
       </a>
      </g>
      <path d="M866 40h10"></path>
      <path d="M 876 40 h 20 m -10 -10 v 20 m 10 -20 v 20"></path>
     </g>
    </svg>
   </div>
   <p>The first dotted sequence of <em>identifier</em>s is the <em>module-name</em>, which identifies the module owning the translation unit. If present, the second dotted sequence of <em>identifier</em>s is the <em>partition-name</em>, which identifies the translation unit as being importable within the same module.</p>
   <p>If the optional <code class="highlight"><span class="k">export</span></code> keyword is absent, there shall be no <em>partition-name</em>, and <em>module-declaration</em> implicitly imports the interface unit of the module. See <a href="#import-visibility">§4.2 Transitive visibility of imports</a> for the semantics of imports.</p>
   <p><code class="highlight"><span class="n">module</span></code> is a context-sensitive keyword that is recognized only in the formation of a <em>module-declaration</em> at the start of a translation unit.</p>
   <h4 class="heading settled" data-level="3.2.2" id="import-decl"><span class="secno">3.2.2. </span><span class="content"><em>import-declaration</em>s</span><a class="self-link" href="#import-decl"></a></h4>
   <p>The general form of an <em>import-declaration</em> is:</p>
   <div class="railroad">
    <svg class="railroad-diagram" height="191" viewBox="0 0 776 191" width="776">
     <g transform="translate(.5 .5)">
      <path d="M 20 30 v 20 m 10 -20 v 20 m -10 -10 h 20.5"></path>
      <g>
       <path d="M40 40h0"></path>
       <path d="M284 40h0"></path>
       <path d="M40 40a10 10 0 0 0 10 -10v0a10 10 0 0 1 10 -10"></path>
       <g>
        <path d="M60 20h204"></path>
       </g>
       <path d="M264 20a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path>
       <path d="M40 40h20"></path>
       <g class="non-terminal">
        <path d="M60 40h0"></path>
        <path d="M264 40h0"></path>
        <rect height="22" width="204" x="60" y="29"></rect>
        <a href="">
         <text x="162" y="44">attribute-specifier-seq</text>
         <text x="162" y="44">attribute-specifier-seq</text>
        </a>
       </g>
       <path d="M264 40h20"></path>
      </g>
      <g>
       <path d="M284 40h0"></path>
       <path d="M392 40h0"></path>
       <path d="M284 40h20"></path>
       <g>
        <path d="M304 40h68"></path>
       </g>
       <path d="M372 40h20"></path>
       <path d="M284 40a10 10 0 0 1 10 10v0a10 10 0 0 0 10 10"></path>
       <g class="terminal">
        <path d="M304 60h0"></path>
        <path d="M372 60h0"></path>
        <rect height="22" rx="10" ry="10" width="68" x="304" y="49"></rect>
        <a href="">
         <text x="338" y="64">public</text>
         <text x="338" y="64">public</text>
        </a>
       </g>
       <path d="M372 60a10 10 0 0 0 10 -10v0a10 10 0 0 1 10 -10"></path>
       <path d="M284 40a10 10 0 0 1 10 10v30a10 10 0 0 0 10 10"></path>
       <g class="terminal">
        <path d="M304 90h0"></path>
        <path d="M372 90h0"></path>
        <rect height="22" rx="10" ry="10" width="68" x="304" y="79"></rect>
        <a href="">
         <text x="338" y="94">export</text>
         <text x="338" y="94">export</text>
        </a>
       </g>
       <path d="M372 90a10 10 0 0 0 10 -10v-30a10 10 0 0 1 10 -10"></path>
      </g>
      <path d="M392 40h10"></path>
      <g class="terminal">
       <path d="M402 40h0"></path>
       <path d="M470 40h0"></path>
       <rect height="22" rx="10" ry="10" width="68" x="402" y="29"></rect>
       <a href="">
        <text x="436" y="44">import</text>
        <text x="436" y="44">import</text>
       </a>
      </g>
      <path d="M470 40h10"></path>
      <g>
       <path d="M480 40h0"></path>
       <path d="M688 40h0"></path>
       <path d="M480 40h20"></path>
       <g>
        <path d="M500 40h24"></path>
        <path d="M644 40h24"></path>
        <path d="M524 40h10"></path>
        <g class="non-terminal">
         <path d="M534 40h0"></path>
         <path d="M634 40h0"></path>
         <rect height="22" width="100" x="534" y="29"></rect>
         <a href="">
          <text x="584" y="44">identifier</text>
          <text x="584" y="44">identifier</text>
         </a>
        </g>
        <path d="M634 40h10"></path>
        <path d="M534 40a10 10 0 0 0 -10 10v10a10 10 0 0 0 10 10"></path>
        <g class="terminal">
         <path d="M534 70h36"></path>
         <path d="M598 70h36"></path>
         <rect height="22" rx="10" ry="10" width="28" x="570" y="59"></rect>
         <a href="">
          <text x="584" y="74">.</text>
          <text x="584" y="74">.</text>
         </a>
        </g>
        <path d="M634 70a10 10 0 0 0 10 -10v-10a10 10 0 0 0 -10 -10"></path>
       </g>
       <path d="M668 40h20"></path>
       <path d="M480 40a10 10 0 0 1 10 10v40a10 10 0 0 0 10 10"></path>
       <g>
        <path d="M500 100h0"></path>
        <path d="M668 100h0"></path>
        <g class="terminal">
         <path d="M500 100h0"></path>
         <path d="M528 100h0"></path>
         <rect height="22" rx="10" ry="10" width="28" x="500" y="89"></rect>
         <a href="">
          <text x="514" y="104">:</text>
          <text x="514" y="104">:</text>
         </a>
        </g>
        <path d="M528 100h10"></path>
        <path d="M538 100h10"></path>
        <g>
         <path d="M548 100h0"></path>
         <path d="M668 100h0"></path>
         <path d="M548 100h10"></path>
         <g class="non-terminal">
          <path d="M558 100h0"></path>
          <path d="M658 100h0"></path>
          <rect height="22" width="100" x="558" y="89"></rect>
          <a href="">
           <text x="608" y="104">identifier</text>
           <text x="608" y="104">identifier</text>
          </a>
         </g>
         <path d="M658 100h10"></path>
         <path d="M558 100a10 10 0 0 0 -10 10v10a10 10 0 0 0 10 10"></path>
         <g class="terminal">
          <path d="M558 130h36"></path>
          <path d="M622 130h36"></path>
          <rect height="22" rx="10" ry="10" width="28" x="594" y="119"></rect>
          <a href="">
           <text x="608" y="134">.</text>
           <text x="608" y="134">.</text>
          </a>
         </g>
         <path d="M658 130a10 10 0 0 0 10 -10v-10a10 10 0 0 0 -10 -10"></path>
        </g>
       </g>
       <path d="M668 100a10 10 0 0 0 10 -10v-40a10 10 0 0 1 10 -10"></path>
       <path d="M480 40a10 10 0 0 1 10 10v100a10 10 0 0 0 10 10"></path>
       <g class="non-terminal">
        <path d="M500 160h30"></path>
        <path d="M638 160h30"></path>
        <rect height="22" width="108" x="530" y="149"></rect>
        <a href="">
         <text x="584" y="164">header-name</text>
         <text x="584" y="164">header-name</text>
        </a>
       </g>
       <path d="M668 160a10 10 0 0 0 10 -10v-100a10 10 0 0 1 10 -10"></path>
      </g>
      <path d="M688 40h10"></path>
      <g class="terminal">
       <path d="M698 40h0"></path>
       <path d="M726 40h0"></path>
       <rect height="22" rx="10" ry="10" width="28" x="698" y="29"></rect>
       <a href="">
        <text x="712" y="44">;</text>
        <text x="712" y="44">;</text>
       </a>
      </g>
      <path d="M726 40h10"></path>
      <path d="M 736 40 h 20 m -10 -10 v 20 m 10 -20 v 20"></path>
     </g>
    </svg>
   </div>
   <p>An <em>import-declaration</em> specifies that the named translation unit is to be imported. Following the <code class="highlight"><span class="n">import</span></code> is either a <em>module-name</em>, identifying the module to be imported, or a <code class="highlight"><span class="o">:</span></code> and a <em>partition-name</em>, identifying a partition of the current module to be imported (<a href="#partitions">§3.3 Module partitions</a>), or a <em>header-name</em>, identifying a legacy header unit to be imported (<a href="#legacy-headers">§6 Legacy headers</a>).</p>
   <p><code class="highlight"><span class="n">import</span></code> is a context-sensitive keyword that is recognized only in the formation of an <em>import-declaration</em> in the block of <em>import-declaration</em>s at the start of a translation unit.</p>
   <p>The semantics of imports are described in <a href="#imports">§4 Imports</a>.</p>
   <h3 class="heading settled" data-level="3.3" id="partitions"><span class="secno">3.3. </span><span class="content">Module partitions</span><a class="self-link" href="#partitions"></a></h3>
   <p>A module partition is a module unit that can be imported into other module units of the same module. Each module partition has a unique name suffix, which is separated from the <em>module-name</em> by a colon. Module partitions are an implementation detail of their containing module that is not observable to code outside the module. In particular, a module partition cannot be imported from outside its module.</p>
   <p>Module partitions permit the interface of a module to be factored across several files. They also permit module-internal declarations to be moved to a file that is imported but not re-exported by the module’s interface unit, while leaving implementation details visible to the interface unit itself. Finally, they permit implementation details to be shared between multiple translation units of a module without putting those implementation details into the module interface unit.</p>
   <p>Unlike for a module implementation unit, the <em>module-declaration</em> of a module partition does not implicitly import the interface unit of the module. As a consequence, the interface unit of the module may choose to import (and re-export, if it desires) a module partition without creating an import cycle. Alternatively, a module partition may import the interface unit of the module if desired.</p>
   <div class="example" id="example-445164f8">
    <a class="self-link" href="#example-445164f8"></a> 
<pre class="highlight"><span class="k">export</span> <span class="n">module</span> <span class="nl">widget</span><span class="p">:</span><span class="n">base</span><span class="p">;</span>
<span class="k">export</span> <span class="k">class</span> <span class="nc">Widget</span> <span class="p">{};</span>
</pre>
<pre class="highlight"><span class="k">export</span> <span class="n">module</span> <span class="nl">widget</span><span class="p">:</span><span class="n">bolt</span><span class="p">;</span>
<span class="nl">import</span> <span class="p">:</span><span class="n">base</span><span class="p">;</span>
<span class="k">export</span> <span class="k">class</span> <span class="nc">Bolt</span> <span class="o">:</span> <span class="n">Widget</span> <span class="p">{};</span>
</pre>
<pre class="highlight"><span class="k">export</span> <span class="n">module</span> <span class="n">widget</span><span class="p">;</span>
<span class="k">export</span> <span class="nl">import</span> <span class="p">:</span><span class="n">base</span><span class="p">;</span>
<span class="k">export</span> <span class="nl">import</span> <span class="p">:</span><span class="n">bolt</span><span class="p">;</span>
<span class="kt">void</span> <span class="nf">frob</span><span class="p">(</span><span class="n">Widget</span><span class="o">*</span><span class="p">);</span>
</pre>
<pre class="highlight"><span class="k">export</span> <span class="n">module</span> <span class="nl">widget</span><span class="p">:</span><span class="n">utils</span><span class="p">;</span>
<span class="n">import</span> <span class="n">widget</span><span class="p">;</span> <span class="c1">// make Widget, Bolt, frob visible</span>
<span class="c1"></span><span class="n">import</span> <span class="n">std</span><span class="p">.</span><span class="n">vector</span><span class="p">;</span>
<span class="kr">inline</span> <span class="kt">void</span> <span class="nf">frob_helper</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">Widget</span><span class="o">*></span> <span class="o">&amp;</span><span class="n">widgets</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">for</span> <span class="p">(</span><span class="n">Widget</span> <span class="o">*</span><span class="nl">w</span> <span class="p">:</span> <span class="n">widgets</span><span class="p">)</span> <span class="n">frob</span><span class="p">(</span><span class="n">w</span><span class="p">);</span>
<span class="p">}</span>
</pre>
<pre class="highlight"><span class="n">module</span> <span class="n">widget</span><span class="p">;</span>
<span class="nl">import</span> <span class="p">:</span><span class="n">utils</span><span class="p">;</span>
<span class="kt">void</span> <span class="nf">frob</span><span class="p">(</span><span class="n">Widget</span> <span class="o">*</span><span class="n">w</span><span class="p">)</span> <span class="p">{</span>
  <span class="n">frob_helper</span><span class="p">(</span><span class="n">children</span><span class="p">(</span><span class="n">w</span><span class="p">));</span>
<span class="p">}</span>
</pre>
    <p>Here, the module partitions <code class="highlight"><span class="o">:</span><span class="n">base</span></code> and <code class="highlight"><span class="o">:</span><span class="n">bolt</span></code> are re-exported by the interface unit, and so their interfaces contribute to the interface of the module. The module partition <code class="highlight"><span class="o">:</span><span class="n">utils</span></code> is not exported by the interface unit, and is not part of the module’s interface. However, it wishes to refer to symbols declared in the interface unit, and therefore must import the interface unit. The final translation unit in this example is an implementation unit, whose <em>module-declaration</em> implicitly imports the interface unit. However, the partition <code class="highlight"><span class="o">:</span><span class="n">utils</span></code> must be explicitly imported here to make the name <code class="highlight"><span class="n">frob_helper</span></code> visible.</p>
   </div>
   <p><code class="highlight"><span class="k">export</span></code> declarations in a module partition only have an effect if the module partition is exported by the interface unit. Implementations are encouraged to issue a warning if a module partition that contains an <code class="highlight"><span class="k">export</span></code> declaration is not re-exported by the module’s interface unit.</p>
   <h2 class="heading settled" data-level="4" id="imports"><span class="secno">4. </span><span class="content">Imports</span><a class="self-link" href="#imports"></a></h2>
   <p>Importing a translation unit makes its interface available to the importing code. This includes declaration names, semantic effects of declarations, and macros.</p>
   <p>The interface of a module can be imported by importing its interface unit, partitions of the current module can be imported by name, and legacy header modules can be imported to import the interface of a legacy header file. All forms of import follow the same rules.</p>
   <h3 class="heading settled" data-level="4.1" id="import-semantics"><span class="secno">4.1. </span><span class="content">Import semantics</span><a class="self-link" href="#import-semantics"></a></h3>
   <p>Import declarations have the following effect:</p>
   <ul>
    <li data-md="">
     <p>The imported translation unit is identified.</p>
    <li data-md="">
     <p>All namespace-scope names and macros exported by that translation unit are
made visible in the current translation unit.</p>
    <li data-md="">
     <p>The semantic effects of all declarations in the imported translation unit take
effect in the current translation unit.</p>
   </ul>
   <p>If the imported translation unit and the current translation unit are owned by the same module, all namespace-scope names and macros from the imported translation unit are made visible in the current translation unit, regardless of whether they are exported.</p>
   <p>The semantic effects that are imported from a translation unit include</p>
   <ul>
    <li data-md="">
     <p>whether a class is defined (and if so, its member names),</p>
    <li data-md="">
     <p>whether a default argument is available,</p>
    <li data-md="">
     <p>the existence and definitions of template specializations,</p>
    <li data-md="">
     <p>definitions of constexpr functions,</p>
   </ul>
   <p>and so on. Imported semantic effects are said to be <dfn data-dfn-type="dfn" data-noexport="" id="available">available<a class="self-link" href="#available"></a></dfn> in the importing translation unit.</p>
   <div class="example" id="example-d40aa977">
    <a class="self-link" href="#example-d40aa977"></a> 
<pre class="highlight"><span class="k">export</span> <span class="n">module</span> <span class="n">widget</span><span class="p">;</span>
<span class="k">struct</span> <span class="n">Widget</span> <span class="p">{</span> <span class="kt">int</span> <span class="n">get</span><span class="p">();</span> <span class="p">};</span>
<span class="k">export</span> <span class="n">Widget</span> <span class="nf">make</span><span class="p">();</span>
</pre>
<pre class="highlight"><span class="n">import</span> <span class="n">widget</span><span class="p">;</span>
<span class="kt">int</span> <span class="nf">f</span><span class="p">()</span> <span class="p">{</span>
  <span class="k">auto</span> <span class="n">w</span> <span class="o">=</span> <span class="n">make</span><span class="p">();</span> <span class="c1">// ok, name 'make' and definition of class Widget are imported</span>
<span class="c1"></span>  <span class="k">return</span> <span class="n">w</span><span class="p">.</span><span class="n">get</span><span class="p">();</span> <span class="c1">// ok, type definition is imported</span>
<span class="c1"></span><span class="p">}</span>
<span class="n">Widget</span> <span class="n">w</span><span class="p">;</span> <span class="c1">// error, name 'Widget' is not visible here</span>
</pre>
    <p>The behavior is the same no matter whether <code class="highlight"><span class="k">struct</span> <span class="n">Widget</span></code>'s definition appears before or after the <code class="highlight"><span class="n">make</span></code> function. For example, this definition of the interface unit of <code class="highlight"><span class="n">widget</span></code> is exactly equivalent to the one above:</p>
<pre class="highlight"><span class="k">export</span> <span class="n">module</span> <span class="n">widget</span><span class="p">;</span>
<span class="k">struct</span> <span class="n">Widget</span><span class="p">;</span>
<span class="k">export</span> <span class="n">Widget</span> <span class="nf">make</span><span class="p">();</span>
<span class="k">struct</span> <span class="n">Widget</span> <span class="p">{</span> <span class="kt">int</span> <span class="n">get</span><span class="p">();</span> <span class="p">};</span>
</pre>
   </div>
   <p>Names and semantic properties are not exported transitively by default.</p>
   <div class="example" id="example-0fd2e80e">
    <a class="self-link" href="#example-0fd2e80e"></a> 
<pre class="highlight"><span class="k">export</span> <span class="n">module</span> <span class="nl">handle</span><span class="p">:</span><span class="n">impl</span><span class="p">;</span>
<span class="k">struct</span> <span class="n">Impl</span> <span class="p">{</span> <span class="kt">int</span> <span class="n">n</span><span class="p">;</span> <span class="p">};</span>
</pre>
<pre class="highlight"><span class="k">export</span> <span class="n">module</span> <span class="n">handle</span><span class="p">;</span>
<span class="nl">import</span> <span class="p">:</span><span class="n">impl</span><span class="p">;</span>
<span class="k">export</span> <span class="k">using</span> <span class="n">Handle</span> <span class="o">=</span> <span class="n">Impl</span> <span class="o">*</span><span class="p">;</span>
<span class="k">export</span> <span class="n">Handle</span> <span class="nf">make</span><span class="p">();</span>
</pre>
<pre class="highlight"><span class="n">import</span> <span class="n">handle</span><span class="p">;</span>
<span class="kt">int</span> <span class="nf">f</span><span class="p">()</span> <span class="p">{</span>
  <span class="n">Handle</span> <span class="n">h</span> <span class="o">=</span> <span class="n">make</span><span class="p">();</span>
  <span class="k">return</span> <span class="n">h</span><span class="o">-></span><span class="n">n</span><span class="p">;</span> <span class="c1">// error, definition of Impl is not available here</span>
<span class="c1"></span><span class="p">}</span>
</pre>
   </div>
   <p>Cyclic imports are disallowed.</p>
   <div class="note" role="note">
     <strong>Rationale:</strong> 
    <p>We take it as an ideal that the semantics of a translation unit should not depend on the order in which its constituent declarations appear. Therefore, all semantic effects in the translation unit are exported, regardless of whether they occur before or after an <code class="highlight"><span class="k">export</span></code> declaration. (In the <code class="highlight"><span class="n">widget</span></code> example, it does not matter whether <code class="highlight"><span class="k">struct</span> <span class="n">Widget</span></code> is defined before or after <code class="highlight"><span class="n">make</span></code>.)</p>
    <p>Only semantic effects that are in some way reachable from an exported declaration need actually be made available to importers of the translation unit. An implementation can still prune out those effects that are purely internal, such as the definition of a non-exported class that is not made reachable by any exported declaration.</p>
    <p>As demonstrated in the <code class="highlight"><span class="n">handle</span></code> example, it is straightforward to separate out semantic effects that exist only for use by the implementation of the module (including use within the interface unit itself) so they are not visible to consumers of the module.</p>
   </div>
   <h3 class="heading settled" data-level="4.2" id="import-visibility"><span class="secno">4.2. </span><span class="content">Transitive visibility of imports</span><a class="self-link" href="#import-visibility"></a></h3>
   <p>Three different forms of import are available, providing control over the transitive visibility of names and semantic effects of imported translation units:</p>
<pre class="highlight"><span class="n">import</span> <span class="n">foo</span><span class="p">.</span><span class="n">bar</span><span class="p">;</span> <span class="c1">// a private import</span>
<span class="c1"></span><span class="k">public</span> <span class="n">import</span> <span class="n">foo</span><span class="p">.</span><span class="n">bar</span><span class="p">;</span> <span class="c1">// a public import</span>
<span class="c1"></span><span class="k">export</span> <span class="n">import</span> <span class="n">foo</span><span class="p">.</span><span class="n">bar</span><span class="p">;</span> <span class="c1">// an exported import</span>
</pre>
   <h4 class="heading settled" data-level="4.2.1" id="private-imports"><span class="secno">4.2.1. </span><span class="content">Private imports</span><a class="self-link" href="#private-imports"></a></h4>
<pre class="highlight"><span class="n">import</span> <span class="n">foo</span><span class="p">.</span><span class="n">bar</span><span class="p">;</span>
</pre>
   <p>By default, the imports of a translation unit are not made visible to
translation units that import it in any way: names of declarations and macros
from the imported translation unit are not transitively made visible, and
definitions of entities, default arguments, and so on are not made available
transitively. Such an import is known as a <dfn data-dfn-type="dfn" data-noexport="" id="private-import">private import<a class="self-link" href="#private-import"></a></dfn>.</p>
   <p>This default is appropriate when an import is intended for the consumption of
the translation unit itself and does not form part of its interface: this
permits the maintainer of the translation unit to remove imports that they are
no longer using, without risk of breaking downstream consumers of the
translation unit who are inadvertently (or deliberately) depending on it.</p>
   <h4 class="heading settled" data-level="4.2.2" id="exported-imports"><span class="secno">4.2.2. </span><span class="content">Exported imports</span><a class="self-link" href="#exported-imports"></a></h4>
<pre class="highlight"><span class="k">export</span> <span class="n">import</span> <span class="n">foo</span><span class="p">.</span><span class="n">bar</span><span class="p">;</span>
</pre>
   <p>An import can be preceded by the <code class="highlight"><span class="k">export</span></code> keyword, forming an <dfn data-dfn-type="dfn" data-lt="exported import" data-noexport="" id="exported-import">exported
import<a class="self-link" href="#exported-import"></a></dfn>. This makes the imported translation unit transitively visible.
Importing a translation unit containing an exported import is equivalent to
importing that translation unit and also importing the translation unit named
by the exported import, except that macros are not implicitly re-exported (see <a href="#macro-export">§5.2 Macro export</a>).</p>
   <p>This form of import is appropriate when the interface of one translation unit is
intended to form part of the interface of another translation unit by aggregation.</p>
   <h4 class="heading settled" data-level="4.2.3" id="public-imports"><span class="secno">4.2.3. </span><span class="content">Public imports</span><a class="self-link" href="#public-imports"></a></h4>
<pre class="highlight"><span class="k">public</span> <span class="n">import</span> <span class="n">foo</span><span class="p">.</span><span class="n">bar</span><span class="p">;</span>
</pre>
   <p>A <dfn data-dfn-type="dfn" data-noexport="" id="public-import">public import<a class="self-link" href="#public-import"></a></dfn> provides a hybrid between the default importation
mode and an exported import. No names or macros from the imported translation
unit are made visible in importers of the current translation unit (unless
explicitly re-exported), but all the other semantic properties of the imported
translation unit do take effect. This permits a translation unit to export an
interface that is a modified form of the interface of another translation unit.</p>
   <div class="example" id="example-18e0277b">
    <a class="self-link" href="#example-18e0277b"></a> 
<pre class="highlight"><span class="n">module</span> <span class="n">std</span><span class="p">.</span><span class="n">cstdlib</span><span class="p">;</span>
<span class="k">public</span> <span class="n">import</span> <span class="o">&lt;</span><span class="n">stdlib</span><span class="p">.</span><span class="n">h</span><span class="o">></span><span class="p">;</span>
<span class="k">export</span> <span class="k">namespace</span> <span class="n">std</span> <span class="p">{</span>
  <span class="k">using</span> <span class="o">::</span><span class="n">atof</span><span class="p">;</span>
  <span class="k">using</span> <span class="o">::</span><span class="n">atol</span><span class="p">;</span>
  <span class="c1">// …</span>
<span class="c1"></span>  <span class="k">using</span> <span class="o">::</span><span class="n">div</span><span class="p">;</span>
  <span class="c1">// ...</span>
<span class="c1"></span>  <span class="k">using</span> <span class="o">::</span><span class="kt">div_t</span><span class="p">;</span> <span class="c1">// exported as a complete type because we publicly imported &lt;stdlib.h></span>
<span class="c1"></span>  <span class="k">using</span> <span class="o">::</span><span class="kt">size_t</span><span class="p">;</span>
<span class="p">}</span>
<span class="cp">#export EXIT_FAILURE</span>
<span class="cp">#export EXIT_SUCCESS</span>
<span class="cp">#export MB_CUR_MAX</span>
<span class="cp">#export NULL</span>
<span class="cp">#export RAND_MAX</span>
</pre>
<pre class="highlight"><span class="n">import</span> <span class="n">std</span><span class="p">.</span><span class="n">cstdlib</span><span class="p">;</span>
<span class="kt">void</span> <span class="nf">f</span><span class="p">()</span> <span class="p">{</span>
  <span class="n">std</span><span class="o">::</span><span class="kt">div_t</span> <span class="n">a</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">div</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="mi">3</span><span class="p">);</span> <span class="c1">// ok, definition of div_t is available</span>
<span class="c1"></span>  <span class="kt">div_t</span> <span class="n">a</span> <span class="o">=</span> <span class="n">div</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="mi">3</span><span class="p">);</span> <span class="c1">// error, names 'div_t' and 'div' are not visible here</span>
<span class="c1"></span><span class="p">}</span>
</pre>
   </div>
   <h3 class="heading settled" data-level="4.3" id="import-and-cpp"><span class="secno">4.3. </span><span class="content">Preprocessor impact</span><a class="self-link" href="#import-and-cpp"></a></h3>
   <p><code class="highlight"><span class="n">module</span></code> and <code class="highlight"><span class="n">import</span></code> declarations affect both the behavior of the C++ language in phase 7 of translation onwards, and the behavior of the C++ preprocessor, as imports may introduce macro names. To support this, a restriction is applied to the initial sequence of <em>preprocessing-token</em>s from which these declarations are derived:</p>
   <ul>
    <li data-md="">
     <p>The terminating semicolon of a <em>module-declaration</em> or <em>import-declaration</em> shall not be produced by a macro expansion, and shall not be preceded by the expansion of an imported macro.</p>
   </ul>
   <p>The preprocessor is expected to identify the initial <em>module-declaration</em> and sequence of <em>import-declaration</em>s as it produces them, and to apply the semantic effects of those declarations at the point of the corresponding semicolon. The preprocessor and compiler proper may share a representation for a precompiled translation unit, or may use distinct representations or some other implementation technique, but must interpret the imported translation unit name as naming the same notional translation unit.</p>
   <p>The token following an <code class="highlight"><span class="n">import</span></code> token can be a <em>header-name</em> token, such as an angled string literal token (for example <code class="highlight"><span class="o">&lt;</span><span class="n">foo</span><span class="o">></span></code>). Such tokens are only formed in special situations (currently, after a <code class="highlight"><span class="cp">#include</span></code> or a <code class="highlight"><span class="n">__has_include</span><span class="p">(</span></code>), and the use of a <em>header-name</em> token in an <em>import-declaration</em> adds one more such situation. As such, after lexing an <code class="highlight"><span class="n">import</span></code> token that might form part of an <em>import-declaration</em>, the following token is lexed as a <em>header-name</em> token if possible. If the token after the <em>header-name</em> token is not a <code class="highlight"><span class="p">;</span></code> token, the <em>header-name</em> token must be reverted and re-processed as regular non-<em>header-name</em> tokens.</p>
   <div class="note" role="note">
     <strong>Rationale:</strong> 
    <p>The terminating semicolon is required to literally appear within the
translation unit source code in order to avoid any ambiguity as to where
imported macros become available for use. As an example of the problems that
could otherwise arise, consider:</p>
<pre class="highlight"><span class="c1">// foo exports a macro "#define BAR baz"</span>
<span class="c1"></span><span class="cp">#define IMPORT import foo; BAR</span>
<span class="cp"></span><span class="n">IMPORT</span>
</pre>
    <p>Depending on whether the effect of the import occurs during or after rescan
of the expansion of the <code class="highlight"><span class="n">IMPORT</span></code> macro, the <code class="highlight"><span class="n">BAR</span></code> macro from <code class="highlight"><span class="n">foo</span></code> may or may
not be expanded. This is avoided by requiring the <code class="highlight"><span class="p">;</span></code> (the point at which
macros become visible) to not be produced by macro expansion.</p>
    <p>We also wish to permit the set of imports of a translation unit to be
determined without knowledge of the contents of the imported translation units.
In particular, the full set of dependencies should be discoverable
(for instance, by a build tool or a non-compiler
parser of source code) without the need to consult external files, safe in the
knowledge that no macro will (for instance) <code class="highlight"><span class="cp">#define import</span></code>. However,
preprocessor action should still be permitted in the import declaration region,
to allow constructs such as:</p>
<pre class="highlight"><span class="cp">#ifdef BUILDING_ON_UNIX</span>
<span class="cp"></span><span class="n">import</span> <span class="n">support</span><span class="p">.</span><span class="n">unix</span><span class="p">;</span>
<span class="cp">#else</span>
<span class="cp"></span><span class="n">import</span> <span class="n">support</span><span class="p">.</span><span class="n">windows</span><span class="p">;</span>
<span class="cp">#endif</span>
</pre>
    <p>To this end, macro expansion before the end of the initial sequence of <em>import-declaration</em>s is disallowed from expanding an imported macro.
(However, imported macros are still visible from the terminating semicolon
of the relevant import declaration, as we need to update the preprocessor
state immediately in case the first non-import declaration begins with
a use of an imported macro.)</p>
   </div>
   <h2 class="heading settled" data-level="5" id="exports"><span class="secno">5. </span><span class="content">Exports</span><a class="self-link" href="#exports"></a></h2>
   <h3 class="heading settled" data-level="5.1" id="name-export"><span class="secno">5.1. </span><span class="content">Name export</span><a class="self-link" href="#name-export"></a></h3>
   <p>A namespace-scope declaration can be exported by prefixing it with the <code class="highlight"><span class="k">export</span></code> keyword:</p>
   <div class="railroad">
    <svg class="railroad-diagram" height="101" viewBox="0 0 432 101" width="432">
     <g transform="translate(.5 .5)">
      <path d="M 20 21 v 20 m 10 -20 v 20 m -10 -10 h 20.5"></path>
      <path d="M40 31h10"></path>
      <g class="terminal">
       <path d="M50 31h0"></path>
       <path d="M118 31h0"></path>
       <rect height="22" rx="10" ry="10" width="68" x="50" y="20"></rect>
       <a href="">
        <text x="84" y="35">export</text>
        <text x="84" y="35">export</text>
       </a>
      </g>
      <path d="M118 31h10"></path>
      <g>
       <path d="M128 31h0"></path>
       <path d="M392 31h0"></path>
       <path d="M128 31h20"></path>
       <g class="non-terminal">
        <path d="M148 31h58"></path>
        <path d="M314 31h58"></path>
        <rect height="22" width="108" x="206" y="20"></rect>
        <a href="">
         <text x="260" y="35">declaration</text>
         <text x="260" y="35">declaration</text>
        </a>
       </g>
       <path d="M372 31h20"></path>
       <path d="M128 31a10 10 0 0 1 10 10v10a10 10 0 0 0 10 10"></path>
       <g>
        <path d="M148 61h0"></path>
        <path d="M372 61h0"></path>
        <g class="terminal">
         <path d="M148 61h0"></path>
         <path d="M176 61h0"></path>
         <rect height="22" rx="10" ry="10" width="28" x="148" y="50"></rect>
         <a href="">
          <text x="162" y="65">{</text>
          <text x="162" y="65">{</text>
         </a>
        </g>
        <path d="M176 61h10"></path>
        <path d="M186 61h10"></path>
        <g>
         <path d="M196 61h0"></path>
         <path d="M324 61h0"></path>
         <path d="M196 61h10"></path>
         <g class="non-terminal">
          <path d="M206 61h0"></path>
          <path d="M314 61h0"></path>
          <rect height="22" width="108" x="206" y="50"></rect>
          <a href="">
           <text x="260" y="65">declaration</text>
           <text x="260" y="65">declaration</text>
          </a>
         </g>
         <path d="M314 61h10"></path>
         <path d="M206 61a10 10 0 0 0 -10 10v0a10 10 0 0 0 10 10"></path>
         <g>
          <path d="M206 81h108"></path>
         </g>
         <path d="M314 81a10 10 0 0 0 10 -10v0a10 10 0 0 0 -10 -10"></path>
        </g>
        <path d="M324 61h10"></path>
        <path d="M334 61h10"></path>
        <g class="terminal">
         <path d="M344 61h0"></path>
         <path d="M372 61h0"></path>
         <rect height="22" rx="10" ry="10" width="28" x="344" y="50"></rect>
         <a href="">
          <text x="358" y="65">}</text>
          <text x="358" y="65">}</text>
         </a>
        </g>
       </g>
       <path d="M372 61a10 10 0 0 0 10 -10v-10a10 10 0 0 1 10 -10"></path>
      </g>
      <path d="M 392 31 h 20 m -10 -10 v 20 m 10 -20 v 20"></path>
     </g>
    </svg>
   </div>
   <div class="example" id="example-8ec6e785">
    <a class="self-link" href="#example-8ec6e785"></a> 
<pre class="highlight"><span class="k">export</span> <span class="k">struct</span> <span class="n">X</span> <span class="p">{</span> <span class="p">...</span> <span class="p">};</span>
</pre>
   </div>
   <p>Such a declaration shall declare at least one namespace-scope name, and all namespace-scope names declared within an <code class="highlight"><span class="k">export</span></code> declaration (including names transitively declared within a namespace inside the declaration) are exported. The export rules apply only to names, but apply uniformly to all kinds of names (including names of <em>using-declaration</em>s and other kinds of declarations that do not introduce new entities).</p>
   <p>The name of a namespace is exported if it is ever declared within an <em>export-declaration</em>. A namespace name is also implicitly exported if any name within it is exported (recursively).</p>
   <div class="example" id="example-0975edef">
    <a class="self-link" href="#example-0975edef"></a> 
<pre class="highlight"><span class="k">export</span> <span class="n">module</span> <span class="n">namespaces</span><span class="p">;</span>
<span class="k">export</span> <span class="k">namespace</span> <span class="n">A</span> <span class="p">{</span> <span class="c1">// A is exported</span>
<span class="c1"></span>  <span class="kt">int</span> <span class="n">n</span><span class="p">;</span> <span class="c1">// A::n is exported</span>
<span class="c1"></span><span class="p">}</span>
<span class="k">namespace</span> <span class="n">B</span> <span class="p">{</span>
  <span class="k">export</span> <span class="kt">int</span> <span class="n">n</span><span class="p">;</span> <span class="c1">// B::n is exported and B is implicitly exported</span>
<span class="c1"></span><span class="p">}</span>
<span class="k">namespace</span> <span class="n">C</span> <span class="p">{</span>
  <span class="kt">int</span> <span class="n">n</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">export</span> <span class="k">namespace</span> <span class="n">C</span> <span class="p">{}</span> <span class="c1">// C is exported, C::n is not</span>
</pre>
   </div>
   <p>Names not declared at namespace scope (for example, names of class members, enumerators of local or scoped enumerations, and class-scope friend declarations) are visible if the enclosing definition is available (that is, if the semantic effect of defining the class has either occurred in the current translation unit or has been imported from another translation unit).</p>
   <div class="example" id="example-a7cccdf0">
    <a class="self-link" href="#example-a7cccdf0"></a> 
<pre class="highlight"><span class="k">export</span> <span class="n">module</span> <span class="n">A</span><span class="p">;</span>
<span class="k">class</span> <span class="nc">NotExported</span> <span class="p">{</span>
  <span class="k">friend</span> <span class="kt">void</span> <span class="n">munge</span><span class="p">(</span><span class="n">NotExported</span><span class="p">);</span>
  <span class="k">friend</span> <span class="kt">void</span> <span class="nf">frob</span><span class="p">(</span><span class="n">NotExported</span><span class="p">);</span>
  <span class="kt">void</span> <span class="nf">badger</span><span class="p">();</span>
<span class="p">};</span>
<span class="kt">void</span> <span class="nf">frob</span><span class="p">(</span><span class="n">NotExported</span><span class="p">);</span>
<span class="k">export</span> <span class="n">NotExported</span> <span class="nf">make</span><span class="p">();</span>
</pre>
<pre class="highlight"><span class="n">import</span> <span class="n">A</span><span class="p">;</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
  <span class="k">auto</span> <span class="n">x</span> <span class="o">=</span> <span class="n">make</span><span class="p">();</span>
  <span class="n">x</span><span class="p">.</span><span class="n">badger</span><span class="p">();</span>  <span class="c1">// OK, definition of 'NotExported' is visible</span>
<span class="c1"></span>  <span class="n">munge</span><span class="p">(</span><span class="n">x</span><span class="p">);</span>    <span class="c1">// OK, found by ADL inside definition of 'NotExported'</span>
<span class="c1"></span>
  <span class="n">NotExported</span> <span class="n">ne</span><span class="p">;</span>   <span class="c1">// ill-formed: NotExported not visible</span>
<span class="c1"></span>  <span class="k">auto</span> <span class="o">*</span><span class="n">fp</span> <span class="o">=</span> <span class="o">&amp;</span><span class="n">frob</span><span class="p">;</span> <span class="c1">// ill-formed: frob is not visible, class-scope</span>
<span class="c1"></span>                    <span class="c1">// declaration only visible to ADL</span>
<span class="c1"></span><span class="p">}</span>
</pre>
   </div>
   <p>An exported name shall not have internal linkage. Exported namespace-scope variables with <code class="highlight"><span class="k">const</span></code>-qualified types do not implicitly have internal linkage.</p>
   <h3 class="heading settled" data-level="5.2" id="macro-export"><span class="secno">5.2. </span><span class="content">Macro export</span><a class="self-link" href="#macro-export"></a></h3>
   <div class="note" role="note"> <strong>Note:</strong> This section is a separable, pure extension to the rest of this proposal, and we would consider it feasible to relegate this feature to a compatibility Annex or to a separate TS that is not intended to ever be merged into the IS. In the absence of a macro export syntax, only legacy header imports (<code class="highlight"><span class="n">import</span> <span class="o">&lt;</span><span class="n">header</span><span class="o">></span><span class="p">;</span></code> and <code class="highlight"><span class="n">import</span> <span class="s">"header.h"</span><span class="p">;</span></code>) can result in macro import; regular <em>import-declaration</em>s cannot. </div>
   <p>Macros can be exported using the <code class="highlight"><span class="cp">#export</span></code> directive.</p>
   <div class="example" id="example-b52dfd9d">
    <a class="self-link" href="#example-b52dfd9d"></a> 
<pre class="highlight"><span class="cp">#define FOO(x) ((x) + 1)</span>
<span class="cp">#export FOO</span>
</pre>
   </div>
   <p>The traditional C preprocessor assumes that <code class="highlight"><span class="cp">#define</span></code>s and <code class="highlight"><span class="cp">#undef</span></code>s occur in a single linear order, but that is no longer the case once macros can be exported and imported. To resolve conflicts between macro definitions across translation units, the following rules are used:</p>
   <ul>
    <li data-md="">
     <p>Each definition and undefinition of a macro is considered to be a distinct entity.</p>
    <li data-md="">
     <p>Such entities are visible if they are from the current translation unit, or if they were exported from a translation unit that has been imported.</p>
    <li data-md="">
     <p>A <code class="highlight"><span class="cp">#define X</span></code> or <code class="highlight"><span class="cp">#undef X</span></code> directive <em>overrides</em> all definitions of <code class="highlight"><span class="n">X</span></code> that are visible at the point of the directive.</p>
    <li data-md="">
     <p>A <code class="highlight"><span class="cp">#define</span></code> or <code class="highlight"><span class="cp">#undef</span></code> directive is <em>active</em> if it is visible and no visible directive overrides it.</p>
    <li data-md="">
     <p>A set of macro directives is <em>consistent</em> if it consists of only <code class="highlight"><span class="cp">#undef</span></code> directives, or if all <code class="highlight"><span class="cp">#define</span></code> directives in the set define the macro name to the same sequence of tokens (following the usual rules for macro redefinitions).</p>
    <li data-md="">
     <p>If a macro name is used and the set of active directives is not consistent, the program is ill-formed. Otherwise, the (unique) meaning of the macro name is used.</p>
   </ul>
   <div class="example" id="example-f1d122b8">
    <a class="self-link" href="#example-f1d122b8"></a> Suppose: 
    <ul>
     <li data-md="">
      <p><code class="highlight"><span class="o">&lt;</span><span class="n">stdio</span><span class="p">.</span><span class="n">h</span><span class="o">></span></code> defines a macro <code class="highlight"><span class="n">getc</span></code> (and exports its <code class="highlight"><span class="cp">#define</span></code>)</p>
     <li data-md="">
      <p><code class="highlight"><span class="o">&lt;</span><span class="n">cstdio</span><span class="o">></span></code> imports the <code class="highlight"><span class="o">&lt;</span><span class="n">stdio</span><span class="p">.</span><span class="n">h</span><span class="o">></span></code> module and undefines the macro (and exports its <code class="highlight"><span class="cp">#undef</span></code>)</p>
    </ul>
    <p>The <code class="highlight"><span class="cp">#undef</span></code> overrides the <code class="highlight"><span class="cp">#define</span></code>, and a source file that imports both modules (in any order) will not see <code class="highlight"><span class="n">getc</span></code> defined as a macro.</p>
   </div>
   <p>Note that the effect of a sequence of imports does not depend on the relative ordering of those imports, but nonetheless permits macros to be overridden as in traditional use of the preprocessor.</p>
   <p><code class="highlight"><span class="cp">#export</span></code> also supports macro name globbing; the token sequence after <code class="highlight"><span class="cp">#export</span></code> is required to be an alternating sequence of <em>identifier</em> or <em>pp-number</em> tokens and <code class="highlight"><span class="o">*</span></code> tokens, where a <code class="highlight"><span class="o">*</span></code> matches any sequence of characters in a macro name.</p>
   <div class="example" id="example-0e540e15">
    <a class="self-link" href="#example-0e540e15"></a> 
<pre class="highlight"><span class="n">import</span> <span class="o">&lt;</span><span class="n">intttypes</span><span class="p">.</span><span class="n">h</span><span class="o">></span><span class="p">;</span>
<span class="cp">#export SCN*</span>
<span class="cp">#export PRI*</span>
</pre>
<pre class="highlight"><span class="n">import</span> <span class="o">&lt;</span><span class="n">limits</span><span class="p">.</span><span class="n">h</span><span class="o">></span><span class="p">;</span>
<span class="cp">#export *_MIN</span>
<span class="cp">#export *_MAX</span>
</pre>
   </div>
   <p>During rescan of an expansion of a macro that was exported from another translation unit, all macros exported from that translation unit are visible.</p>
   <div class="example" id="example-5cbcc2c0">
    <a class="self-link" href="#example-5cbcc2c0"></a> 
<pre class="highlight"><span class="k">export</span> <span class="n">module</span> <span class="n">a</span><span class="p">;</span>
<span class="cp">#define FOO BAR</span>
<span class="cp">#define BAR BAZ</span>
<span class="cp">#export *</span>
</pre>
<pre class="highlight"><span class="k">export</span> <span class="n">module</span> <span class="n">b</span><span class="p">;</span>
<span class="n">import</span> <span class="n">a</span><span class="p">;</span>
<span class="cp">#export FOO</span>
</pre>
<pre class="highlight"><span class="n">import</span> <span class="n">b</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">BAR</span><span class="p">;</span> <span class="c1">// unchanged</span>
<span class="c1"></span><span class="kt">int</span> <span class="n">FOO</span><span class="p">;</span> <span class="c1">// expands to "int BAZ;" even though macro BAR is not visible here</span>
</pre>
   </div>
   <div class="note" role="note">
     <strong>Rationale:</strong> 
    <p>Macros form part of the interface of many modern C++ libraries. Any system that seeks to support exporting C++ interfaces must therefore provide a mechanism to allow macros to be exported. This could instead be accomplished by forcing the macros into a separate, textually-included file, but doing so forces an awkward artificial separation between portions of the same interface, prevents existing header files from being transparently converted into equivalent importable translation units, and makes it error-prone to maintain a library that provides both a header file interface and an importable interface.</p>
   </div>
   <h2 class="heading settled" data-level="6" id="legacy-headers"><span class="secno">6. </span><span class="content">Legacy headers</span><a class="self-link" href="#legacy-headers"></a></h2>
   <p>Legacy header support permits existing header files to be used from modular code without sacrificing modularity: names do not leak into the imported header file, compilation performance is not sacrificed by recompiling the same header files on every inclusion, and users do not need to resort to the preprocessor to access the interfaces of non-modular libraries.</p>
   <h3 class="heading settled" data-level="6.1" id="legacy-header-units"><span class="secno">6.1. </span><span class="content">Legacy header units</span><a class="self-link" href="#legacy-header-units"></a></h3>
   <p>Legacy header units are translation units synthesized by the implementation to wrap an existing header file as part of a module. Each legacy header unit has as its name a <em>header-name</em> that identifies the wrapped file. The synthesized legacy header unit comprises:</p>
<pre class="highlight"><code class="highlight"><span class="k"><span class="k">export</span></span> <span class="n"><span class="n">module</span></span> <i><span class="n"><span class="n">header</span></span><span class="o"><span class="o">-</span></span><span class="n"><span class="n">name</span></span></i> <span class="p"><span class="p">;</span></span>
<span class="k"><span class="k">export</span></span> <span class="k"><span class="k">extern</span></span> <span class="s"><span class="s">"C++"</span></span> <span class="p"><span class="p">{</span></span>
<span class="cp"><span class="cp">#include</span></span> <i>header-name</i><span class="cp"></span><span class="cp"></span>
<span class="cp"><span class="cp">#export *</span></span>
<span class="cp"></span><span class="p"><span class="cp"></span><span class="p">}</span></span>
</code></pre>
   <p>(where the <em>header-name</em> here is for exposition only; a <em>header-name</em> is not a valid module name).</p>
   <p>The entire contents of the header file are exported, including all names, macros, and semantic effects. The entities within the header are treated as not being owned by any module.</p>
   <p>As a special exception, if the module declares an entity with internal linkage (or an entity whose name involves such an entity), the export is not ill-formed, but the program is ill-formed if the entity is odr-used by the importer (including within a template instantiation whose point of instantiation is outside the legacy header unit).</p>
   <p>The <em>header-name</em> in a header import declaration is first looked up as the name of a legacy header unit of the current module (if any). If that lookup fails, it is looked up in direct dependency modules; if it is found, it shall only be found in one such module. Finally, if that lookup also fails, the header import declaration is conditionally-supported. (An implementation is permitted, but not required, to translate the named header into a legacy header unit, or to perform lookup in additional modules, to satisfy the import.)</p>
   <h3 class="heading settled" data-level="6.2" id="include-translation"><span class="secno">6.2. </span><span class="content"><code class="highlight"><span class="cp">#include</span></code> translation</span><a class="self-link" href="#include-translation"></a></h3>
   <p>Within a legacy header unit, a preprocessor directive</p>
<pre class="highlight"><span class="cp">#include</span> FILE<span class="cp"></span>
</pre>
   <p>is interpreted as including a file comprising <code class="highlight"><span class="n">import</span> <span class="kt">FILE</span><span class="p">;</span></code> if <code class="highlight"><span class="kt">FILE</span></code> is a <em>header-name</em> naming another legacy header unit owned by the current module or one of its direct dependencies. Unlike a regular <code class="highlight"><span class="n">import</span></code>, such a <code class="highlight"><span class="cp">#include</span></code> may appear anywhere in the translation unit.</p>
   <p>If the <em>header-name</em> does not correspond to a legacy header unit of the current module or one of its direct dependencies, it is textually included. This is appropriate for headers that are intended to interact with the preprocessor in ways more complex than providing macros as output (for instance, files that depend on the macro state at the point when they are imported), or for files that are intended to generate raw tokens rather than an encapsulated set of declarations.</p>
   <div class="note" role="note">
     <strong>Rationale:</strong> 
    <p>It would be undesirable and inefficient for the translation unit generated for a legacy header unit to contain the contents of the transitive closure of <code class="highlight"><span class="cp">#include</span></code>s in its header; a translation unit importing many such headers would transitively import a great many copies of the same declarations and definitions. In order to approximate the ideal that each entity has only one definition in the entire program, <code class="highlight"><span class="cp">#include</span></code>d headers encountered while building legacy module units should be treated as imports where possible.</p>
    <p>As <code class="highlight"><span class="cp">#include</span></code> may also be used to include files that fundamentally intend to have a textual effect on the compilation, translation from header file <code class="highlight"><span class="cp">#include</span></code>s to <code class="highlight"><span class="n">import</span></code> is not fully automated, and some module must nominate the header file as a legacy header unit for the translation to occur.</p>
   </div>
   <h3 class="heading settled" data-level="6.3" id="legacy-header-compilation"><span class="secno">6.3. </span><span class="content">Compilation model</span><a class="self-link" href="#legacy-header-compilation"></a></h3>
   <div class="note" role="note"> <strong>Note:</strong> This section is purely informative and is not part of the proposal. </div>
   <p>Multiple implementation strategies are possible for supporting legacy headers. The Clang implementation of header module support (which has been in use in production by multiple parties for several years) has validated the feasibility of both a cached in-process compilation-on-demand model and an ahead-of-time separate compilation model. The GCC implementation of the Modules TS has gained experience with allowing the compiler to "call back" into the build system to request module dependencies, and this system also seems feasible for implementing legacy header unit support.</p>
   <p>Possibly the most straightforward approach would be to compile the module interface unit and the legacy header units as part of a single compilation action, passing the names of all relevant files to the compiler together; this compilation action would produce a binary representation of the module interface (the emerging convention is to call this a "BMI" per <a data-link-type="biblio" href="#biblio-gccmodules">[GCCModules]</a>).</p>
   <div class="example" id="example-06731f5f">
    <a class="self-link" href="#example-06731f5f"></a> Source files: 
<pre class="highlight"><span class="c1">// widget.h: some pre-existing widget library</span>
<span class="c1">// ...</span>
</pre>
<pre class="highlight"><span class="c1">// gromit.h: some specific widget</span>
<span class="c1"></span><span class="cp">#include</span> "widget.h"  // transparently imports legacy header unit for "widget.h"<span class="cp"></span>
<span class="cp"></span><span class="c1">// ... </span>
</pre>
<pre class="highlight"><span class="c1">// widget.cppm</span>
<span class="c1">// provide a module interface that exposes only widget.h and not gromit.h</span>
<span class="c1"></span><span class="k">export</span> <span class="n">module</span> <span class="n">widget</span><span class="p">;</span>
<span class="k">export</span> <span class="n">import</span> <span class="s">"widget.h"</span><span class="p">;</span>
</pre>
<pre class="highlight"><span class="c1">// legacy_user.cpp</span>
<span class="c1"></span><span class="cp">#include</span> "gromit.h"  // transparently imports legacy header unit for "gromit.h"<span class="cp"></span>
<span class="cp"></span><span class="c1">// ...</span>
</pre>
<pre class="highlight"><span class="c1">// modern_user.cpp</span>
<span class="c1"></span><span class="n">import</span> <span class="n">widget</span><span class="p">;</span>
<span class="c1">// ...</span>
</pre>
    <p>Compilation commands:</p>
<pre class="highlight">$ <span class="n">cc</span> <span class="o">-</span><span class="n">fmodules</span> <span class="n">widget</span><span class="p">.</span><span class="n">cppm</span> <span class="n">widget</span><span class="p">.</span><span class="n">h</span> <span class="n">gromit</span><span class="p">.</span><span class="n">h</span> <span class="o">--</span><span class="n">precompile</span> <span class="o">-</span><span class="n">o</span> <span class="n">widget</span><span class="p">.</span><span class="n">pcm</span>
$ <span class="n">cc</span> <span class="o">-</span><span class="n">fmodules</span> <span class="o">-</span><span class="n">fmodule</span><span class="o">-</span><span class="n">file</span><span class="o">=</span><span class="n">widget</span><span class="p">.</span><span class="n">pcm</span> <span class="n">legacy_user</span><span class="p">.</span><span class="n">cpp</span> <span class="o">-</span><span class="n">c</span> <span class="o">-</span><span class="n">o</span> <span class="n">legacy_user</span><span class="p">.</span><span class="n">o</span>
$ <span class="n">cc</span> <span class="o">-</span><span class="n">fmodules</span> <span class="o">-</span><span class="n">fmodule</span><span class="o">-</span><span class="n">file</span><span class="o">=</span><span class="n">widget</span><span class="p">.</span><span class="n">pcm</span> <span class="n">modern_user</span><span class="p">.</span><span class="n">cpp</span> <span class="o">-</span><span class="n">c</span> <span class="o">-</span><span class="n">o</span> <span class="n">modern_user</span><span class="p">.</span><span class="n">o</span>
</pre>
    <p>Compiling all the legacy header units of a module as part of the same build action allows the compiler to resolve the dependencies between them (compiling them in topological order) without any need for explicit dependencies to be inferred between the header files.</p>
   </div>
   <h2 class="heading settled" data-level="7" id="low-level"><span class="secno">7. </span><span class="content">Low-level design details</span><a class="self-link" href="#low-level"></a></h2>
   <h3 class="heading settled" data-level="7.1" id="template-lookup"><span class="secno">7.1. </span><span class="content">Templates and two-phase name lookup</span><a class="self-link" href="#template-lookup"></a></h3>
   <p>When a template is imported from another translation unit and instantiated, it must have an appropriate set of names and semantic properties available for the instantiation to use. Templates generally rely on names and semantic properties from two sources:</p>
   <ul>
    <li data-md="">
     <p>those provided alongside the template, and</p>
    <li data-md="">
     <p>those provided by the the code directly or indirectly instantiating the template.</p>
   </ul>
   <p>In general, the semantic properties (and, for argument-dependent lookup, names) provided alongside the template may include properties introduced either before or after the template is defined.</p>
   <p>Note that if one template instantiation triggers another, the inner template instantiation may rely on names and properties provided by the outer template instantiation and on those provided at its point of instantiation. Therefore, we define the visibility rules for template instantiation as follows:</p>
   <p>Within a template instantiation, the <em>path of instantiation</em> is a sequence of locations within the program, starting from the ultimate point of instantiation, via each intervening template instantiation, terminating at the instantiation in question. Names are visible and semantic properties are available within template instantiations if they would be visible or available at any point along the path of instantiation, or (for points outside the current translation unit) would be visible or available at the end of the translation unit containing the relevant point of instantiation.</p>
   <div class="example" id="example-f2437577">
    <a class="self-link" href="#example-f2437577"></a> This example is borrowed from <strong>[temp.dep.res]</strong> in <a data-link-type="biblio" href="#biblio-n4720">[N4720]</a>, adjusted suitably for this proposal. 
<pre class="highlight"><span class="k">export</span> <span class="n">module</span> <span class="n">A</span><span class="p">;</span>
<span class="k">export</span> <span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="n">T</span><span class="o">></span>
<span class="kt">void</span> <span class="n">f</span><span class="p">(</span><span class="n">T</span> <span class="n">t</span><span class="p">)</span> <span class="p">{</span>
  <span class="n">t</span> <span class="o">+</span> <span class="n">t</span><span class="p">;</span>  <span class="c1">// #1</span>
<span class="c1"></span><span class="p">}</span>
</pre>
<pre class="highlight"><span class="k">export</span> <span class="n">module</span> <span class="n">B</span><span class="p">;</span>
<span class="n">import</span> <span class="n">A</span><span class="p">;</span>
<span class="k">export</span> <span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="n">T</span><span class="p">,</span> <span class="k">typename</span> <span class="n">U</span><span class="o">></span>
<span class="kt">void</span> <span class="n">g</span><span class="p">(</span><span class="n">T</span> <span class="n">t</span><span class="p">,</span> <span class="n">U</span> <span class="n">u</span><span class="p">)</span> <span class="p">{</span>
  <span class="n">f</span><span class="p">(</span><span class="n">t</span><span class="p">);</span>  <span class="c1">// #2</span>
<span class="c1"></span><span class="p">}</span>
</pre>
<pre class="highlight"><span class="k">export</span> <span class="n">module</span> <span class="n">C</span><span class="p">;</span>
<span class="n">import</span> <span class="o">&lt;</span><span class="n">string</span><span class="o">></span><span class="p">;</span>
<span class="n">import</span> <span class="n">B</span><span class="p">;</span>
<span class="k">export</span> <span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="n">T</span><span class="o">></span>
<span class="kt">void</span> <span class="n">h</span><span class="p">(</span><span class="n">T</span> <span class="n">t</span><span class="p">)</span> <span class="p">{</span>
  <span class="n">g</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">{</span> <span class="p">},</span> <span class="n">t</span><span class="p">);</span>  <span class="c1">// #3</span>
<span class="c1"></span><span class="p">}</span>
</pre>
<pre class="highlight"><span class="n">import</span> <span class="n">C</span><span class="p">;</span>
<span class="kt">void</span> <span class="nf">i</span><span class="p">()</span> <span class="p">{</span>
  <span class="n">h</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>  <span class="c1">// #4</span>
<span class="c1"></span><span class="p">}</span>
</pre>
    <p>The instantiation of <code class="highlight"><span class="n">f</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">></span></code> has a path of instantiation comprising:</p>
    <ul>
     <li data-md="">
      <p>Point <code class="highlight"><span class="cp">#4</span></code> within <code class="highlight"><span class="n">i</span><span class="p">()</span></code></p>
     <li data-md="">
      <p>Point <code class="highlight"><span class="cp">#3</span></code> within <code class="highlight"><span class="n">h</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">></span><span class="p">(</span><span class="kt">int</span><span class="p">)</span></code></p>
     <li data-md="">
      <p>Point <code class="highlight"><span class="cp">#2</span></code> within <code class="highlight"><span class="n">g</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">,</span> <span class="kt">int</span><span class="o">></span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">,</span> <span class="kt">int</span><span class="p">)</span></code></p>
     <li data-md="">
      <p>Point <code class="highlight"><span class="cp">#1</span></code> within <code class="highlight"><span class="n">f</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">></span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">)</span></code></p>
    </ul>
    <p>Therefore, semantic properties available at point #4, as well as those available in the module interface units of modules <code class="highlight"><span class="n">A</span></code>, <code class="highlight"><span class="n">B</span></code>, and <code class="highlight"><span class="n">C</span></code>, are available within the instantiation of <code class="highlight"><span class="n">f</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">></span></code>. Because the <code class="highlight"><span class="o">&lt;</span><span class="n">string</span><span class="o">></span></code> legacy header unit is imported into the interface unit of module <code class="highlight"><span class="n">C</span></code>, declarations from that header are visible in the instantiation, so the expression <code class="highlight"><span class="n">t</span> <span class="o">+</span> <span class="n">t</span></code> at line #1 is valid.</p>
   </div>
   <div class="note" role="note">
     <strong>Rationale:</strong> 
    <p>This rule makes a necessary and sufficient set of names and properties visible. Each translation unit contributing a template involved in the instantiation could provide one of the types or functions that is intended to be used by the instantiation, so must be included. And the instantiation could be performed with only this set of translation units involved, so any other types and functions are not guaranteed to be available to an instantiation.</p>
   </div>
   <h2 class="heading settled" data-level="8" id="ack"><span class="secno">8. </span><span class="content">Acknowledgements</span><a class="self-link" href="#ack"></a></h2>
   <p>Thanks to David Blaikie, Chandler Carruth, Daniel Dunbar, Duncan Exon Smith, David Jones, Thomas Köppe, Bruno Cardoso Lopes, and Vassil Vassilev for comments on early drafts of this proposal.</p>
   <p>Thanks again to all those involved in the Modules TS, and particularly Gabriel Dos Reis, for exploring the modules design space and providing a basis for this paper.</p>
   <p>Thanks to Doug Gregor et al for the initial design of Clang’s modules implementation, on which the legacy header support in this paper is based.</p>
  </main>
<script>
(function() {
  "use strict";
  var collapseSidebarText = '<span aria-hidden="true">←</span> '
                          + '<span>Collapse Sidebar</span>';
  var expandSidebarText   = '<span aria-hidden="true">→</span> '
                          + '<span>Pop Out Sidebar</span>';
  var tocJumpText         = '<span aria-hidden="true">↑</span> '
                          + '<span>Jump to Table of Contents</span>';

  var sidebarMedia = window.matchMedia('screen and (min-width: 78em)');
  var autoToggle   = function(e){ toggleSidebar(e.matches) };
  if(sidebarMedia.addListener) {
    sidebarMedia.addListener(autoToggle);
  }

  function toggleSidebar(on) {
    if (on == undefined) {
      on = !document.body.classList.contains('toc-sidebar');
    }

    /* Don’t scroll to compensate for the ToC if we’re above it already. */
    var headY = 0;
    var head = document.querySelector('.head');
    if (head) {
      // terrible approx of "top of ToC"
      headY += head.offsetTop + head.offsetHeight;
    }
    var skipScroll = window.scrollY < headY;

    var toggle = document.getElementById('toc-toggle');
    var tocNav = document.getElementById('toc');
    if (on) {
      var tocHeight = tocNav.offsetHeight;
      document.body.classList.add('toc-sidebar');
      document.body.classList.remove('toc-inline');
      toggle.innerHTML = collapseSidebarText;
      if (!skipScroll) {
        window.scrollBy(0, 0 - tocHeight);
      }
      tocNav.focus();
      sidebarMedia.addListener(autoToggle); // auto-collapse when out of room
    }
    else {
      document.body.classList.add('toc-inline');
      document.body.classList.remove('toc-sidebar');
      toggle.innerHTML = expandSidebarText;
      if (!skipScroll) {
        window.scrollBy(0, tocNav.offsetHeight);
      }
      if (toggle.matches(':hover')) {
        /* Unfocus button when not using keyboard navigation,
           because I don’t know where else to send the focus. */
        toggle.blur();
      }
    }
  }

  function createSidebarToggle() {
    /* Create the sidebar toggle in JS; it shouldn’t exist when JS is off. */
    var toggle = document.createElement('a');
      /* This should probably be a button, but appearance isn’t standards-track.*/
    toggle.id = 'toc-toggle';
    toggle.class = 'toc-toggle';
    toggle.href = '#toc';
    toggle.innerHTML = collapseSidebarText;

    sidebarMedia.addListener(autoToggle);
    var toggler = function(e) {
      e.preventDefault();
      sidebarMedia.removeListener(autoToggle); // persist explicit off states
      toggleSidebar();
      return false;
    }
    toggle.addEventListener('click', toggler, false);


    /* Get <nav id=toc-nav>, or make it if we don’t have one. */
    var tocNav = document.getElementById('toc-nav');
    if (!tocNav) {
      tocNav = document.createElement('p');
      tocNav.id = 'toc-nav';
      /* Prepend for better keyboard navigation */
      document.body.insertBefore(tocNav, document.body.firstChild);
    }
    /* While we’re at it, make sure we have a Jump to Toc link. */
    var tocJump = document.getElementById('toc-jump');
    if (!tocJump) {
      tocJump = document.createElement('a');
      tocJump.id = 'toc-jump';
      tocJump.href = '#toc';
      tocJump.innerHTML = tocJumpText;
      tocNav.appendChild(tocJump);
    }

    tocNav.appendChild(toggle);
  }

  var toc = document.getElementById('toc');
  if (toc) {
    createSidebarToggle();
    toggleSidebar(sidebarMedia.matches);

    /* If the sidebar has been manually opened and is currently overlaying the text
       (window too small for the MQ to add the margin to body),
       then auto-close the sidebar once you click on something in there. */
    toc.addEventListener('click', function(e) {
      if(e.target.tagName.toLowerCase() == "a" && document.body.classList.contains('toc-sidebar') && !sidebarMedia.matches) {
        toggleSidebar(false);
      }
    }, false);
  }
  else {
    console.warn("Can’t find Table of Contents. Please use <nav id='toc'> around the ToC.");
  }

  /* Wrap tables in case they overflow */
  var tables = document.querySelectorAll(':not(.overlarge) > table.data, :not(.overlarge) > table.index');
  var numTables = tables.length;
  for (var i = 0; i < numTables; i++) {
    var table = tables[i];
    var wrapper = document.createElement('div');
    wrapper.className = 'overlarge';
    table.parentNode.insertBefore(wrapper, table);
    wrapper.appendChild(table);
  }

})();
</script>
  <h2 class="no-num no-ref heading settled" id="index"><span class="content">Index</span><a class="self-link" href="#index"></a></h2>
  <h3 class="no-num no-ref heading settled" id="index-defined-here"><span class="content">Terms defined by this specification</span><a class="self-link" href="#index-defined-here"></a></h3>
  <ul class="index">
   <li><a href="#available">available</a><span>, in §4.1</span>
   <li><a href="#exported-import">exported import</a><span>, in §4.2.2</span>
   <li><a href="#implementation-unit">implementation unit</a><span>, in §3.1</span>
   <li><a href="#interface-unit">interface unit</a><span>, in §3.1</span>
   <li><a href="#legacy-header-unit">legacy header unit</a><span>, in §3.1</span>
   <li><a href="#module">module</a><span>, in §3.1</span>
   <li><a href="#module-partition">module partition</a><span>, in §3.1</span>
   <li><a href="#module-unit">module unit</a><span>, in §3.1</span>
   <li><a href="#private-import">private import</a><span>, in §4.2.1</span>
   <li><a href="#public-import">public import</a><span>, in §4.2.3</span>
  </ul>
  <h2 class="no-num no-ref heading settled" id="references"><span class="content">References</span><a class="self-link" href="#references"></a></h2>
  <h3 class="no-num no-ref heading settled" id="informative"><span class="content">Informative References</span><a class="self-link" href="#informative"></a></h3>
  <dl>
   <dt id="biblio-gccmodules">[GCCModules]
   <dd>Nathan Sidwell. <a href="https://gcc.gnu.org/wiki/cxx-modules">GCC C++ Modules wiki page</a>. URL: <a href="https://gcc.gnu.org/wiki/cxx-modules">https://gcc.gnu.org/wiki/cxx-modules</a>
   <dt id="biblio-n4697">[N4697]
   <dd>Barry Hedquist. <a href="https://wg21.link/n4697">NB Comments, ISO/IEC PDTS 21544, C++ Extensions for Modules</a>. URL: <a href="https://wg21.link/n4697">https://wg21.link/n4697</a>
   <dt id="biblio-n4720">[N4720]
   <dd>Gabriel Dos Reis. <a href="http://wg21.link/n4720">Working Draft, Extensions to C++ for Modules</a>. URL: <a href="http://wg21.link/n4720">http://wg21.link/n4720</a>
   <dt id="biblio-p0273r0">[P0273R0]
   <dd>Richard Smith, Chandler Carruth, David Jones. <a href="https://wg21.link/p0273r0">Proposed modules changes from implementation and deployment experience</a>. 12 February 2016. URL: <a href="https://wg21.link/p0273r0">https://wg21.link/p0273r0</a>
   <dt id="biblio-p0678r0">[P0678R0]
   <dd>John Lakos. <a href="https://wg21.link/p0678r0">Business Requrements for Modules</a>. URL: <a href="https://wg21.link/p0678r0">https://wg21.link/p0678r0</a>
   <dt id="biblio-p0713r0">[P0713R0]
   <dd>Daveed Vandevoorde. <a href="https://wg21.link/p0713r0">Identifying Module Source Code</a>. URL: <a href="https://wg21.link/p0713r0">https://wg21.link/p0713r0</a>
   <dt id="biblio-p0774r0">[P0774R0]
   <dd>Nathan Sidwell. <a href="https://wg21.link/p0774r0">Module-decl location</a>. URL: <a href="https://wg21.link/p0774r0">https://wg21.link/p0774r0</a>
   <dt id="biblio-p0775r0">[P0775R0]
   <dd>Nathan Sidwell. <a href="https://wg21.link/p0775r0">module partitions</a>. URL: <a href="https://wg21.link/p0775r0">https://wg21.link/p0775r0</a>
   <dt id="biblio-p0795r0">[P0795R0]
   <dd>Simon Brand, Neil Henning, Michael Wong, Christopher Di Bella, Kenneth Benzie. <a href="https://wg21.link/p0795r0">From Vulkan with love: a plea to reconsider the Module Keyword to be contextual</a>. URL: <a href="https://wg21.link/p0795r0">https://wg21.link/p0795r0</a>
   <dt id="biblio-p0841r0">[P0841R0]
   <dd>Bruno Cardoso Lopes, Adrian Prantl, Duncan P. N. Exon Smith. <a href="https://wg21.link/p0841r0">Modules at scale</a>. URL: <a href="https://wg21.link/p0841r0">https://wg21.link/p0841r0</a>
  </dl>
