<div><br></div><div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Jun 21, 2019 at 5:47 PM Gabriel Dos Reis via Core &lt;<a href="mailto:core@lists.isocpp.org">core@lists.isocpp.org</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">



<div dir="auto">
<div dir="ltr"></div>
<div dir="ltr"><br>
</div>
<div dir="ltr"><br>
On Jun 20, 2019, at 10:45 PM, JF Bastien &lt;<a href="mailto:cxx@jfbastien.com" target="_blank">cxx@jfbastien.com</a>&gt; wrote:<br>
<br>
</div>
<blockquote type="cite">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">Thanks Richard, your description matches the original design intent, and what I thought we&#39;d worded through LEWG / LWG / Core reviews.
<div><br>
</div>
</div>
<br>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">On Thu, Jun 20, 2019 at 6:50 PM Richard Smith &lt;<a href="mailto:richardsmith@google.com" target="_blank">richardsmith@google.com</a>&gt; wrote:<br>
</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div dir="ltr">
<div dir="ltr">On Thu, Jun 20, 2019 at 2:22 PM Richard Smith &lt;<a href="mailto:richardsmith@google.com" target="_blank">richardsmith@google.com</a>&gt; wrote:<br>
</div>
<div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div dir="ltr">
<div>As currently specified, bit_cast from an indeterminate value produces an unspecified value rather than an indeterminate value. That means this can&#39;t be implemented by a simple load on some implementations, and instead will require some kind of removing-the-taint-of-an-uninitialized-value
 operation to be performed. (A similar concern applies to reading from padding bits.)</div>
<div><br>
</div>
<div>Is that the intent?</div>
</div>
</blockquote>
<div><br>
</div>
<div>I chatted with JF about this. The intent is as follows:</div>
<div><br>
</div>
<div> * bits of the input that don&#39;t have defined values result in the corresponding bit of the output being &quot;bad&quot;</div>
<div> * if any part of a scalar object is &quot;bad&quot;, that object has an indeterminate value</div>
</div>
</div>
</blockquote>
<div><br>
</div>
<div>Something to note above: Richard pointed out that the Standard currently doesn&#39;t track bits. We could technically track them and have finer granularity, but that seems much bigger than bit_cast and is worth doing as a separate effort, if at all.</div>
</div>
</div>
</div>
</blockquote>
<div><br>
</div>
<div>I suspect that will invalidate lot of constexpr evaluators.  Is it worth it?</div></div></blockquote><div dir="auto"><br></div><div dir="auto"><br></div><div dir="auto">I’m explicitly saying that such a change is out of scope for this discussion, and I take no stance on whether we should do it or not. </div><div dir="auto"><br></div><div dir="auto"><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto"><div></div></div><div dir="auto">
<blockquote type="cite">
<div dir="ltr">
<div dir="ltr">
<div class="gmail_quote">
<div>What Richard proposes still matches the design intent, even if it&#39;s not as constrained as it could be (basically, we could track bits... but really you&#39;re playing with fire if you need that).</div>
<div><br>
</div>
<div><br>
</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div dir="ltr">
<div class="gmail_quote">
<div>Some examples:</div>
<div><br>
</div>
<div><br>
</div>
<div>struct A { char c; /* char padding : 8; */  short s; };</div>
<div>struct B { char x[4]; };</div>
<div><br>
</div>
<div>B one() {</div>
<div>  A a = {1, 2};</div>
<div>  return std::bit_cast&lt;B&gt;(a);</div>
<div>}</div>
<div><br>
</div>
<div>In one(), the second byte of the object representation of a is bad. That means that the second byte of the produced B object is bad, so x[1] in the produced B object is an indeterminate value. The above function, if declared constexpr, would be usable
 in constant expressions so long as you don&#39;t look at one().x[1].</div>
<div><br>
</div>
<div><br>
</div>
<div>A two() {</div>
<div>  B b;</div>
<div>  b.x[0] = &#39;a&#39;;</div>
<div>  b.x[2] = 1;</div>
<div>  b.x[3] = 2;</div>
<div>  return std::bit_cast&lt;A&gt;(b);</div>
<div>}</div>
<div><br>
</div>
<div>In two(), the second byte of the object representation of b is bad. But a bit_cast to A doesn&#39;t care because it never looks at that byte. The above function returns an A with a fully-defined value. If declared constexpr, it would produce a normal, fully-initialized
 value.</div>
<div><br>
</div>
<div><br>
</div>
<div>int three() {</div>
<div>  int n;</div>
<div>  return std::bit_cast&lt;int&gt;(n);</div>
<div>}</div>
<div class="gmail_quote"><br>
</div>
In three(), the entirety of n is bad. A bit_cast from it produces an int whose value is indeterminate. And because we have an expression of non-byte-like type that produced an indeterminate value, the behavior is undefined.</div>
<div class="gmail_quote"><br>
</div>
<div class="gmail_quote"><br>
</div>
<div class="gmail_quote">B four() {</div>
<div class="gmail_quote">  int n;</div>
<div class="gmail_quote">  return std::bit_cast&lt;B&gt;(n);</div>
<div class="gmail_quote">}</div>
<div class="gmail_quote"><br>
</div>
<div class="gmail_quote">In four(), just like three(), the entirety of n is bad, so the scalar subobjects of B are bad too. But because they&#39;re of byte-like type, that&#39;s OK: we can copy them about and produce them from prvalue expressions.</div>
<div class="gmail_quote"><br>
</div>
<div class="gmail_quote">
<div><br>
</div>
<div>I think the above is captured by the following wording change:</div>
<div><br>
</div>
<div>Change in [bit.cast]p1:</div>
<div><br>
</div>
<div>&quot;&quot;&quot;</div>
<div>Returns: An object of type To. Each bit of the value representation of the result is equal to the<br>
corresponding bit in the object representation of from. Padding bits of the To object are unspecified.<br>
<div></div>
</div>
<div>If there is no value of type To corresponding to the value representation produced, the behavior is<br>
undefined. If there are multiple such values, which value is produced is unspecified.</div>
<div>&lt;ins&gt;A bit in the value representation of the result is indeterminate if does not correspond to a bit in the value</div>
<div>
<div>representation of <font face="courier new, monospace">from</font> or corresponds to a bit of an object that is not within its lifetime or has an indeterminate value ([basic.indet]).</div>
</div>
<div>For each bit in the value representation of the result that is indeterminate,</div>
<div>the smallest object containing that bit has an indeterminate value;</div>
</div>
</div>
</blockquote>
<div><br>
</div>
<div>The above sentence makes me wonder, what effect does it have on:</div>
<div><br>
</div>
<div>struct A { char x[4]; };</div>
<div>union B { int i; short s; };</div>
<div><br>
</div>
<div>A a;</div>
<div>a.x[1] = a.x[2] = a.x[3] = 0;</div>
<div>B b = bit_cast&lt;B&gt;(a);</div>
<div><br>
</div>
<div>?</div>
<div><br>
</div>
<div> </div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div dir="ltr">
<div class="gmail_quote">
<div>the behavior is undefined unless that object is of unsigned ordinary character type or std::byte type.</div>
</div>
</div>
</blockquote>
<div><br>
</div>
<div>What&#39;s the intent / effect of the above?</div>
<div><br>
</div>
<div> </div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div dir="ltr">
<div class="gmail_quote">
<div>The result does not otherwise contain any indeterminate values.&lt;/ins&gt;<br>
</div>
<div>&quot;&quot;&quot;</div>
</div>
</div>
</blockquote>
</div>
</div>
</div>
</blockquote>
</div><div dir="auto"><blockquote type="cite">
<div dir="ltr"><span>_______________________________________________</span><br>
<span>ub mailing list</span><br>
<span><a href="mailto:ub@isocpp.open-std.org" target="_blank">ub@isocpp.open-std.org</a></span><br>
<span><a href="https://nam06.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.open-std.org%2Fmailman%2Flistinfo%2Fub&amp;amp;data=02%7C01%7Cgdr%40microsoft.com%7Cb0c3874ebf0a4d53f6be08d6f60bab69%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636966927331276486&amp;amp;sdata=BE2z9xvEHQzykENxaSjSd6veCjKKscobJl1ON%2B01moo%3D&amp;amp;reserved=0" target="_blank">https://nam06.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.open-std.org%2Fmailman%2Flistinfo%2Fub&amp;amp;data=02%7C01%7Cgdr%40microsoft.com%7Cb0c3874ebf0a4d53f6be08d6f60bab69%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636966927331276486&amp;amp;sdata=BE2z9xvEHQzykENxaSjSd6veCjKKscobJl1ON%2B01moo%3D&amp;amp;reserved=0</a></span><br>
</div>
</blockquote>
</div>

_______________________________________________<br>
Core mailing list<br>
<a href="mailto:Core@lists.isocpp.org" target="_blank">Core@lists.isocpp.org</a><br>
Subscription: <a href="http://lists.isocpp.org/mailman/listinfo.cgi/core" rel="noreferrer" target="_blank">http://lists.isocpp.org/mailman/listinfo.cgi/core</a><br>
Link to this post: <a href="http://lists.isocpp.org/core/2019/06/6736.php" rel="noreferrer" target="_blank">http://lists.isocpp.org/core/2019/06/6736.php</a><br>
</blockquote></div></div>