<div dir="ltr"><div dir="ltr">On Fri, Jun 21, 2019 at 5:46 PM Gabriel Dos Reis &lt;<a href="mailto:gdr@microsoft.com">gdr@microsoft.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="auto">
<div dir="ltr"></div>
<div dir="ltr">On Jun 20, 2019, at 6:51 PM, Richard Smith &lt;<a href="mailto:richardsmith@google.com" target="_blank">richardsmith@google.com</a>&gt; wrote:<br></div><div dir="ltr">
<br>
</div>
<blockquote type="cite">
<div dir="ltr">
<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><br>
</div>
<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>
</div>
</blockquote>
<div><br>
</div>
<div>Hmmm, isn’t it the lvalue-to-rvalue conversion that provokes the UB?  I am asking a question regarding the actual cause of the UB.</div></div></blockquote><div><br></div><div>This doesn&#39;t naturally fall out of the wording, because std::bit_cast takes an lvalue and returns an rvalue, and is specified in terms of poking at an object representation directly without formally performing an lvalue-to-rvalue conversion or hitting the [basic.indet] cases where the undefined value is &quot;observed&quot;.</div><div><br></div><div>And I think that&#39;s actually in some ways a good thing: it shouldn&#39;t matter if some part of the input to bit_cast is uninitialized so long as the destination type has only padding in the uninitialized region.</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="auto"><blockquote type="cite">
<div dir="ltr">
<div dir="ltr">

<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>the behavior is undefined unless that object is of unsigned ordinary character type or std::byte type.</div>
<div>The result does not otherwise contain any indeterminate values.&lt;/ins&gt;<br>
</div>
<div>&quot;&quot;&quot;</div>
</div>
</div>
</div>
</blockquote>
<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="http://www.open-std.org/mailman/listinfo/ub" target="_blank">http://www.open-std.org/mailman/listinfo/ub</a></span><br>
</div>
</blockquote>
</div>

_______________________________________________<br>
ub mailing list<br>
<a href="mailto:ub@isocpp.open-std.org" target="_blank">ub@isocpp.open-std.org</a><br>
<a href="http://www.open-std.org/mailman/listinfo/ub" rel="noreferrer" target="_blank">http://www.open-std.org/mailman/listinfo/ub</a><br>
</blockquote></div></div>