<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta charset="UTF-8"/>
  <meta name="viewport" content="width=device-width, initial-scale=1"/>
  <meta name="title" content="Modular main()"/>

  <title>Modular main()</title>

  <style type="text/css">

html
{
  font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif;
  font-weight: normal;
  font-size: 18px;
  line-height: 1.4em;
  letter-spacing: 0.01em;

  color: #292929;
}

body {margin: 0;} /* There is non-0 default margin for body. */

/* See notes on what's going on here. */
body {min-width: 17em;}
@media only screen and (min-width: 360px)
{
  body {min-width: 19em;}
}

/*
 * Header (optional).
 */

#header-bar
{
  width: 100%;

  background: rgba(0, 0, 0, 0.04);
  border-bottom: 1px solid rgba(0, 0, 0, 0.2);

  padding: .4em 0 .42em 0;
  margin: 0 0 1.4em 0;
}

#header
{
  /* Same as in #content. */
  max-width: 41em;
  margin: 0 auto 0 auto;
  padding: 0 .4em 0 .4em;

  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;

  width: 100%;
  display: table;
  border: none;
  border-collapse: collapse;
}

#header-logo, #header-menu
{
  display: table-cell;
  border: none;
  padding: 0;
  vertical-align: middle;
}

#header-logo {text-align: left;}
#header-menu {text-align: right;}

/* These overlap with #header's margin because of border collapsing. */
#header-logo {padding-left: .4em;}
#header-menu {padding-right: .4em;}

#header-logo a
{
  color: #000;
  text-decoration: none;
  outline: none;
}
#header-logo a:visited {color: #000;}
#header-logo a:hover, #header-logo a:active {color: #000;}

#header-menu a
{
  font-size: 0.889em;
  line-height: 1.4em;
  text-align: right;
  margin-left: 1.2em;
  white-space: nowrap;
  letter-spacing: 0;
}

#header-menu a
{
  color: #000;
  outline: none;
}
#header-menu a:visited {color: #000;}
#header-menu a:hover, #header-menu a:active
{
  color: #3870c0;
  text-decoration: none;
}

/* Flexbox-based improvements though the above works reasonably well. */
#header-menu-body
{
  width: 100%;

  display: -webkit-inline-flex;
  display: inline-flex;

  -webkit-flex-flow: row wrap;
  flex-flow: row wrap;

  -webkit-justify-content: flex-end;
  justify-content: flex-end;
}

/* Whether we want it (and at which point) depends on the size of the menu. */
/*
@media only screen and (max-width: 567px)
{
  #header-menu-body
  {
    -webkit-flex-direction: column;
    flex-direction: column;
  }
}
*/

/*
 * Content.
 */

#content
{
  max-width: 41em;
  margin: 0 auto 0 auto;
  padding: 0 .4em 0 .4em; /* Space between text and browser frame. */

  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}

/*
 * Footer (optional).
 */

#footer
{
  color: #767676;
  font-size: 0.7223em;
  line-height: 1.3em;
  margin: 2.2em 0 1em 0;
  text-align: center;
}

#footer a
{
  color: #767676;
  text-decoration: underline;
}
#footer a:visited {color: #767676;}
#footer a:hover, #footer a:active {color: #3870c0;}

/* Screen size indicator in the footer. The before/after content is in case
   we don't have any content in the footer. Margin is to actually see the
   border separate from the browser frame. */

/*
#footer:before {content: "\A0";}
#footer:after {content: "\A0";}

#footer
{
  border-left: 1px solid;
  border-right: 1px solid;
  margin-left: 1px;
  margin-right: 1px;
}

@media only screen and (max-width: 359px)
{
  #footer {border-color: red;}
}

@media only screen and (min-width: 360px) and (max-width: 567px)
{
  #footer {border-color: orange;}
}

@media only screen and (min-width: 568px) and (max-width: 1023px)
{
  #footer {border-color: blue;}
}

@media only screen and (min-width: 1024px)
{
  #footer {border-color: green;}
}
*/

/*
 * Common elements.
 */

p, li, dd {text-align: justify;}
.code {text-align: left;} /* Manually aligned. */
pre {text-align: left;}   /* If it is inside li/dd. */

/* Notes. */

.note
{
  color: #606060;
}

div.note
{
  margin: 2em 0 2em 0; /* The same top/bottom margings as pre box. */

  padding-left: 0.5em;
  border: 0.25em;
  border-left-style: solid;
  border-color: #808080;

  page-break-inside: avoid;
}

div.note :first-child {margin-top:    0;}
div.note :last-child  {margin-bottom: 0;}

span.note::before {content: "[Note: "}
span.note::after  {content: "]"}

/* Links. */
a
{
  color: #3870c0;
  /*color: #4078c0;*/
  text-decoration: none;
}

a:hover, a:active
{
/*color: #006fbf;*/
/*color: #0087e7;*/
  text-decoration: underline;
}

a:visited
{
/*color: #003388;*/
  color: #00409c;
}

/* Standard lists. */
ul, ol, dl {margin: 1em 0 1em 0;}
ul li, ol li {margin: 0 0 .4em 0;}
ul li {list-style-type: circle;}
dl dt {margin: 0 0 0 0;}
dl dd {margin: 0 0 .6em 1.8em;}

code, pre
{
  font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
  font-size: 0.92em;
  letter-spacing: 0;
}

pre {white-space: pre-wrap;}

@media only screen and (max-width: 567px)
{
  pre {word-break: break-all;}
}

/* Use page rather than system font settings. */
input
{
  font-family: inherit;
  font-weight: inherit;
  font-size:   inherit;
  line-height: inherit;
}

pre
{
  background-color: rgba(0, 0, 0, 0.05);
  border-radius: 0.2em;
  padding: .8em .4em .8em .4em;
  margin: 2em -.4em 2em -.4em; /* Use margins of #content. */
}

code
{
  background-color: rgba(0, 0, 0, 0.05);
  border-radius: 0.2em;
  padding: .2em .32em .18em .32em;
}

/*
code::before
{
  letter-spacing: -0.2em;
  content: "\00a0";
}

code::after
{
  letter-spacing: -0.2em;
  content: "\00a0";
}
*/

/* Bases:
 *
 * common.css
 * pre-box.css
 * code-box.css
 *
 */

#content
{
  max-width: 43.6em;
  padding-left: 3em; /* Reserve for headings. */
}

h1
{
  font-weight: normal;
  font-size: 2em;
  line-height: 1.4em;
  margin: 1.6em 0 .6em -1.4em;
}

h1.preface
{
  margin-left: -.56em;
}

h2
{
  font-weight: normal;
  font-size: 1.556em;
  line-height: 1.4em;
  margin: 1.6em 0 .6em -.8em;
}

h3
{
  font-weight: normal;
  font-size: 1.3em;
  line-height: 1.4em;
  margin: 1.6em 0 .6em -.2em;
}

/* Title page */

#titlepage {
  margin: 0 0 4em 0;
  border-bottom: 1px solid black;
}

#titlepage .title {
  font-weight: normal;
  font-size: 2.333em;
  line-height: 1.4em;
  letter-spacing: 0;
  text-align: center;
  margin: 2em 0 2em 0;
}

#titlepage p {
  font-size: 0.889em;
  line-height: 1.4em;
  margin: 2em 0 .6em 0;
}

table.toc
{
  border-style      : none;
  border-collapse   : separate;
  border-spacing    : 0;

  margin            : 0.2em 0 0.2em 0;
  padding           : 0 0 0 0;
}

table.toc tr
{
  padding           : 0 0 0 0;
  margin            : 0 0 0 0;
}

table.toc * td, table.toc * th {
  border-style      : none;
  margin            : 0 0 0 0;
  vertical-align    : top;
}

table.toc * th
{
  font-weight       : normal;
  padding           : 0 0.8em 0 0;
  text-align        : left;
  white-space       : nowrap;
}

table.toc * table.toc th
{
  padding-left      : 1em;
}

table.toc * td
{
  padding           : 0 0 0 0;
  text-align        : left;
}

table.toc * td.preface
{
  padding-left      : 1.35em;
}


#titlepage .title
{
  font-size: 2em;
}

/*
 * Property list table.
 */
.proplist
{
  width: calc(100%); /* Fill the page. */

  table-layout: fixed;

  border: none;
  border-spacing: 0 0;
}

.proplist th, .proplist td {padding: .1em 0 .1em 0;}

.proplist th
{
  font-weight: normal;
  text-align: left;

  width: 7em;
}
.proplist th:after {content: ":";}
  </style>

</head>
<body>
<div id="content">

  <div id="titlepage">
    <div class="title">Modular main()</div>

    <table class="proplist">
      <tbody>
	<tr><th>Document</th><td><a href="https://wg21.link/P1203R0">P1203R0</a></td></tr>
	<tr><th>Audience</th><td>EWG</td></tr>
	<tr><th>Authors</th><td>Boris Kolpackov (Code Synthesis), Richard Smith (Google)</td></tr>
	<tr><th>Reply-To</th><td>boris@codesynthesis.com, richard@metafoo.co.uk</td></tr>
	<tr><th>Date</th><td>2018-10-05</td></tr>
      </tbody>
    </table>
  </div>
  <h2 id="toc">Contents</h2>

  <table class="toc">
    <tr><th>1</th><td><a href="#abstract">Abstract</a></td></tr>
    <tr><th>2</th><td><a href="#background">Background</a></td></tr>
    <tr><th>3</th><td><a href="#proposal">Proposal</a>
      <table class="toc">
        <tr><th>3.1</th><td><a href="#basic">Basic Functionality</a></td></tr>
        <tr><th>3.2</th><td><a href="#extended">Extended Functionality</a></td></tr>
      </table>
    </td></tr>
  </table>

  <h2 id="abstract">1 Abstract</h2>

  <p><i>This paper discusses the benefits of being able to define
  <code>main()</code> in a module and proposes to allow both exported and
  non-exported variants with slightly different semantics.</i></p>

  <h2 id="background">2 Background</h2>

  <p>Per the discussion at the Bellevue meeting, there appears to be agreement
  that modularizing a codebase should eventually result in the replacement of
  all non-modular translation units with modules. This, however, brings the
  question of what happens to the translation unit that defines
  <code>main()</code>.</p>

  <p>While it will be possible to define <code>main()</code> in the global
  module fragment, this will be both cumbersome and without any clear benefits
  other than making the translation unit itself a module. Specifically, due to
  the restrictions placed on the global module fragment, such a
  <code>main()</code> would have to be defined in a separate file that is
  <code>#include</code>d into the module translation unit. And such a
  definition wouldn't have visibility of the module's names, for example,
  implementation details that would be naturally placed into the module.</p>

  <p>The question is then whether it could be useful to place
  <code>main()</code> into a module and, if so, with what semantics? Placing a
  function into a module's purview affects two orthogonal aspects: <i>name
  visibility</i> and <i>ownership</i>. Specifically, the function now has
  visibility of all the names declared in a module and the function is now
  owned by that module. Let's discuss whether and how each could be useful in
  the context of <code>main()</code>.</p>

  <p>Name visibility would allow "hiding" <code>main()</code>'s implementation
  details (functions, classes) in the same module in order to avoid symbol
  conflicts (currently achieved with <code>static</code> and/or unnamed
  namespaces). For example:</p>

  <pre>export module main;

class application
{
  ...
};

export int main ()
{
  application a;
  a.run ();
}</pre>

  <p>The ability to "see" a module's non-exported names would also be required
  for a module's unit testing. <span class="note">Without modular
  <code>main()</code> the best option is probably to provide an (appropriately
  decorated, for example with the module name) exported test function that is
  then called by the traditional <code>main()</code>.</span></p>

  <p>At first glance, module ownership for <code>main()</code> might appear
  counterproductive; after all, we should have a single <code>main()</code> in
  a program. However, consider module unit testing as an example: a module may
  wish to provide <code>main()</code> that implements its unit tests. And a
  library may contain multiple such modules, which means it may contain
  multiple <code>main()</code>s. In this context, having <code>main()</code>
  owned by a module would avoid any conflicts.</p>

  <div class="note">
  <p>The ability to have a module-specific <code>main()</code> would allow
  combining the module implementation and its unit tests in a single
  translation unit, an arrangement advocated by many modern programming
  languages.</p>
  </div>

  <p>For example:</p>

  <pre>export module util.hashmap;

export class hashmap
{
  ...
};

int main ()
{
  // Unit tests for hashmap.
}</pre>

  <h2 id="proposal">3 Proposal</h2>

  <h3 id="basic">3.1 Basic Functionality</h3>

  <p>We propose to allow defining <code>main()</code> in a module as an
  <i>exported</i> function. Such a definition has visibility of the module's
  names but whether it is owned by the module is implementation-defined (that
  is, it may still be <code>extern "C"</code> and belong to the global
  module). All existing semantics and restrictions, such as that a program
  shall have a single <code>main()</code> function, still apply.</p>

  <h3 id="extended">3.2 Extended Functionality</h3>

  <p>We further propose to allow defining a <i>non-exported</i>
  <code>main()</code> that, in addition to having the module's name
  visibility, would also be owned by the module. Unlike the exported
  <code>main()</code>, a program may contain multiple such functions with one
  of them selected using an implementation-defined mechanism. <span
  class="note">For example, a link-time switch that specifies the module to
  take the <code>main()</code> from.</span></p>

  <div class="note">
  <p>If a program contains both one or more exported <code>main()</code>s and
  a non-exported/non-modular variant, then the latter is selected by
  default.</p>
  </div>

  <div class="note">
  <p>We realize that supporting this extended functionality may require
  additional mechanisms in the underlying linking technology (for example,
  symbol aliasing/redirection). Note, however, that as a last resort an
  implementation can treat a non-exported <code>main()</code> as an ordinary
  function and generate a <i>thunk</i> <code>main()</code> that calls it.</p>
  </div>

</div>

</body>
</html>
