<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <meta http-equiv="Content-Style-Type" content="text/css" />
  <meta name="generator" content="pandoc" />
  <title>LWG 3016 is Not a Defect</title>
  <style type="text/css">code{white-space: pre;}</style>
  <style type="text/css">
a.sourceLine { display: inline-block; line-height: 1.25; }
a.sourceLine { pointer-events: none; color: inherit; text-decoration: inherit; }
a.sourceLine:empty { height: 1.2em; position: absolute; }
.sourceCode { overflow: visible; }
code.sourceCode { white-space: pre; position: relative; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
code.sourceCode { white-space: pre-wrap; }
a.sourceLine { text-indent: -1em; padding-left: 1em; }
}
pre.numberSource a.sourceLine
  { position: relative; }
pre.numberSource a.sourceLine:empty
  { position: absolute; }
pre.numberSource a.sourceLine::before
  { content: attr(data-line-number);
    position: absolute; left: -5em; text-align: right; vertical-align: baseline;
    border: none; pointer-events: all;
    -webkit-touch-callout: none; -webkit-user-select: none;
    -khtml-user-select: none; -moz-user-select: none;
    -ms-user-select: none; user-select: none;
    padding: 0 4px; width: 4em;
    color: #aaaaaa;
  }
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa;  padding-left: 4px; }
div.sourceCode
  {  }
@media screen {
a.sourceLine::before { text-decoration: underline; }
}
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code span.at { color: #7d9029; } /* Attribute */
code span.bn { color: #40a070; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code span.ch { color: #4070a0; } /* Char */
code span.cn { color: #880000; } /* Constant */
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
code span.dt { color: #902000; } /* DataType */
code span.dv { color: #40a070; } /* DecVal */
code span.er { color: #ff0000; font-weight: bold; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #40a070; } /* Float */
code span.fu { color: #06287e; } /* Function */
code span.im { } /* Import */
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
code span.op { color: #666666; } /* Operator */
code span.ot { color: #007020; } /* Other */
code span.pp { color: #bc7a00; } /* Preprocessor */
code span.sc { color: #4070a0; } /* SpecialChar */
code span.ss { color: #bb6688; } /* SpecialString */
code span.st { color: #4070a0; } /* String */
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
  </style>
  <style type="text/css">
  ins {
    color:#009a9a; text-decoration:underline;
  }
  
  del {
    color:red; text-decoration:line-through;
  }
  
  ednote {
    color:blue;
  }
  
  table {
    border-collapse: collapse;
  }
  
  table, th, td {
    border: 1px solid black;
  }
  </style>
</head>
<body>
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="607">
  <tr>
    <td width="172" align="left" valign="top">Document number:</td>
    <td width="435">
      P0899R0
    </td>
  </tr>
  <tr>
    <td width="172" align="left" valign="top">Date:</td>
    <td width="435">2018-01-30</td>
  </tr>
  <tr>
    <td width="172" align="left" valign="top">Project:</td>
    <td width="435">C++ Programming Language, Library Working Group</td>
  </tr>
  <tr>
    <td width="172" align="left" valign="top">Reply-to:</td>
    <td width="435">
      Casey Carter &lt;<a href="mailto:Casey@Carter.net">Casey@Carter.net</a>&gt;<br>
    </td>
  </tr>
</table>
<div id="header">
<h1 class="title">LWG 3016 is Not a Defect</h1>
</div>
<h3>Abstract</h3>
<p><a href="https://cplusplus.github.io/LWG/issue3016">LWG 3016</a> proposes adding the phrase:</p>
<blockquote>
<p>It is implementation-defined whether over-aligned types are supported (6.6.5 <a href="http://eel.is/c++draft/basic.align">[basic.align]</a>).</p>
</blockquote>
<p>to the specification of <code>std::optional</code> in <a href="http://eel.is/c++draft/optional.optional#1">[optional.optional]/1</a>. This proposal:</p>
<ul>
<li>provides rationale for why the change proposed by LWG 3016 is redundant,</li>
<li>proposes closing LWG 3016 as NAD, and</li>
<li>proposes removing similar redundant wording from the Standard Library specification.</li>
</ul>
<h2>Discussion</h2>
<p>Absent explicit specification otherwise, it’s reasonable to assume that the requirements of the core language apply to entities specified in the Standard Library. Specifically, the requirements in <a href="http://eel.is/c++draft/basic.align">[basic.align]</a> apply to the library portions of the standard. Hence, given the specification of a class template <code>S</code>:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode cpp"><code class="sourceCode cpp"><a class="sourceLine" id="cb1-1" data-line-number="1"><span class="kw">template</span> &lt;<span class="kw">class</span> T&gt;</a>
<a class="sourceLine" id="cb1-2" data-line-number="2"><span class="kw">struct</span> S {</a>
<a class="sourceLine" id="cb1-3" data-line-number="3">    T internal; <span class="co">// exposition only</span></a>
<a class="sourceLine" id="cb1-4" data-line-number="4">};</a></code></pre></div>
<p>There is no need to explicitly specify that <a href="http://eel.is/c++draft/basic.align#3">[basic.align]/3</a> applies to “internal”: if <code>T</code> is an over-aligned type, then support for <code>S&lt;T&gt;</code> is implementation-defined. Similarly, the specification of <code>optional&lt;T&gt;</code> in <a href="http://eel.is/c++draft/optional.optional#1">[optional.optional]/1</a>:</p>
<blockquote>
<p>… When an instance of <code>optional&lt;T&gt;</code> <em>contains a value</em>, it means that an object of type <code>T</code>, referred to as the optional object’s contained value, is allocated within the storage of the optional object. Implementations are not permitted to use additional storage, such as dynamic memory, to allocate its contained value. The contained value shall be allocated in a region of the <code>optional&lt;T&gt;</code> storage suitably aligned for the type <code>T</code>. …</p>
</blockquote>
<p>says that the contained value is “suitably aligned” for the type <code>T</code>. Albeit the term “suitably aligned” is not specified, I believe the only reasonable interpretation is that the contained value is aligned accordingly for a subobject of type <code>T</code> - just as in the first case of an exposition-only member - in an implementation-defined manner in accordance with <a href="http://eel.is/c++draft/basic.align#3">[basic.align]/3</a>.</p>
<p>Adding redundant text to <a href="http://eel.is/c++draft/optional.optional#1">[optional.optional]/1</a> would obviously not improve the quality of the Standard; if LWG agrees with the rationale provided herein, then LWG3016 should be closed as NAD.</p>
<h3>Alternative</h3>
<p>If LWG feels that the above interpretation is too subtle to be left implicit, we could add blanket wording in Clause 20 to cover the entire library rather than annotating each individual instance of a library component that may create instances of a user-defined type with a cross-reference to <a href="http://eel.is/c++draft/basic.align">[basic.align]</a>. That requirement could take the form of a new paragraph at the end of Clause 20 (immediately after <a href="http://eel.is/c++draft/lib.types.movedfrom">[lib.types.movedfrom]</a>):</p>
<blockquote>
<p>20.5.5.?? Alignment of program-defined types [lib.types.alignment]</p>
<p>1 [Note: Some library components allocate instances of program-defined object types, either within the storage of an instance of a library-defined object type, or dynamically. The extent to which over-alignment of such program-defined object instances is supported is implementation-defined (<a href="http://eel.is/c++draft/basic.align">[basic.align]</a>). –end note]</p>
</blockquote>
<p>The author feels that such a note does not add significant value; it is presented here only to make LWG aware of the alternative.</p>
<h2>Technical Specifications</h2>
<p>In addition to closing LWG 3016 as NAD, it behooves us to remove similar redundant wording from the rest of the Standard Library specification. Wording relative to <a href="https://wg21.link/n4713">N4713</a>.</p>
<p>Change <a href="http://eel.is/c++draft/variant.variant#1">[variant.variant]/1</a> as follows:</p>
<blockquote>
<p>1 Any instance of <code>variant</code> at any given time either holds a value of one of its alternative types, or it holds no value. When an instance of <code>variant</code> holds a value of alternative type <code>T</code>, it means that a value of type <code>T</code>, referred to as the <code>variant</code> object’s <em>contained value</em>, is allocated within the storage of the <code>variant</code> object. Implementations are not permitted to use additional storage, such as dynamic memory, to allocate the contained value. The contained value shall be allocated in a region of the <code>variant</code> storage suitably aligned for all types in <code>Types...</code>. <del>It is implementation-defined whether over-aligned types are supported.</del></p>
</blockquote>
<p>Change <a href="http://eel.is/c++draft/meta.trans.other">[meta.trans.other]</a> as follows (Note that striking this sentence also resolves <a href="https://github.com/cplusplus/draft/issues/1757">Editorial issue #1757</a> which is currently assigned LWG status):</p>
<blockquote>
<p>[…]</p>
<p>2 <del>It is implementation-defined whether any extended alignment is supported (<a href="http://eel.is/c++draft/basic.align">[basic.align]</a>).</del></p>
<p>[…]</p>
</blockquote>
<p>Change <a href="http://eel.is/c++draft/depr.temporary.buffer">[depr.temporary.buffer]</a> as follows:</p>
<blockquote>
<p>[…]</p>
<p>2 <em>Effects:</em> Obtains a pointer to uninitialized, contiguous storage for <code>N</code> adjacent objects of type <code>T</code>, for some non-negative number <code>N</code>. <del>It is implementation-defined whether over-aligned types are supported (6.6.5).</del></p>
</blockquote>
<p>Change <a href="http://eel.is/c++draft/depr.default.allocator">[depr.default.allocator]</a> as follows (Note: this makes the specification of the deprecated <code>allocator::allocate(size_t, const void*)</code> overload consistent with the non-deprecated <code>allocator::allocate(size_t)</code> overload):</p>
<blockquote>
<p>[…]</p>
<p>3 <em>Returns:</em> A pointer to the initial element of an array of storage of size <code>n * sizeof(T)</code>, aligned appropriately for objects of type <code>T</code>. <del>It is implementation-defined whether over-aligned types are supported (<a href="http://eel.is/c++draft/basic.align">[basic.align]</a>).</del></p>
<p>4 <em>Remarks:</em> The storage is obtained by calling <code>​::​operator new</code><del><code>(std​::​size_­t)</code></del> (<a href="http://eel.is/c++draft/new.delete">[new.delete]</a>), but it is unspecified when or how often this function is called.</p>
</blockquote>
</body>
</html>
