<html><head><meta http-equiv="Content-Type" content="text/html; charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Jun 21, 2019, at 1:45 AM, JF Bastien <<a href="mailto:cxx@jfbastien.com" class="">cxx@jfbastien.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" style="caret-color: rgb(0, 0, 0); font-family: BookmanOldStyle; font-size: 18px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><div dir="ltr" class="">Thanks Richard, your description matches the original design intent, and what I thought we'd worded through LEWG / LWG / Core reviews.<div class=""><br class=""></div></div><br class=""><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Jun 20, 2019 at 6:50 PM Richard Smith <<a href="mailto:richardsmith@google.com" class="">richardsmith@google.com</a>> wrote:<br class=""></div><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-style: solid; border-left-color: rgb(204, 204, 204); padding-left: 1ex;"><div dir="ltr" class=""><div dir="ltr" class="">On Thu, Jun 20, 2019 at 2:22 PM Richard Smith <<a href="mailto:richardsmith@google.com" target="_blank" class="">richardsmith@google.com</a>> wrote:<br class=""></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-style: solid; border-left-color: rgb(204, 204, 204); padding-left: 1ex;"><div dir="ltr" class=""><div class="">As currently specified, bit_cast from an indeterminate value produces an unspecified value rather than an indeterminate value. That means this can'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 class=""><br class=""></div><div class="">Is that the intent?</div></div></blockquote><div class=""><br class=""></div><div class="">I chatted with JF about this. The intent is as follows:</div><div class=""><br class=""></div><div class=""> * bits of the input that don't have defined values result in the corresponding bit of the output being "bad"</div><div class=""> * if any part of a scalar object is "bad", that object has an indeterminate value</div></div></div></blockquote><div class=""><br class=""></div><div class="">Something to note above: Richard pointed out that the Standard currently doesn'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. What Richard proposes still matches the design intent, even if it's not as constrained as it could be (basically, we could track bits... but really you're playing with fire if you need that).</div></div></div></div></blockquote><div><br class=""></div><div><br class=""></div><div>The requirement to track bits would also substantially slow down our constexpr interpreter. (As it is, bit_cast is pretty horrible for us.)</div><div><br class=""></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>Daveed</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" style="caret-color: rgb(0, 0, 0); font-family: BookmanOldStyle; font-size: 18px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><div class="gmail_quote"><div class=""><br class=""></div><div class=""><br class=""></div><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-style: solid; border-left-color: rgb(204, 204, 204); padding-left: 1ex;"><div dir="ltr" class=""><div class="gmail_quote"><div class="">Some examples:</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">struct A { char c; /* char padding : 8; */ short s; };</div><div class="">struct B { char x[4]; };</div><div class=""><br class=""></div><div class="">B one() {</div><div class=""> <span class="Apple-converted-space"> </span>A a = {1, 2};</div><div class=""> <span class="Apple-converted-space"> </span>return std::bit_cast<B>(a);</div><div class="">}</div><div class=""><br class=""></div><div class="">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't look at one().x[1].</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">A two() {</div><div class=""> <span class="Apple-converted-space"> </span>B b;</div><div class=""> <span class="Apple-converted-space"> </span>b.x[0] = 'a';</div><div class=""> <span class="Apple-converted-space"> </span>b.x[2] = 1;</div><div class=""> <span class="Apple-converted-space"> </span>b.x[3] = 2;</div><div class=""> <span class="Apple-converted-space"> </span>return std::bit_cast<A>(b);</div><div class="">}</div><div class=""><br class=""></div><div class="">In two(), the second byte of the object representation of b is bad. But a bit_cast to A doesn'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 class=""><br class=""></div><div class=""><br class=""></div><div class="">int three() {</div><div class=""> <span class="Apple-converted-space"> </span>int n;</div><div class=""> <span class="Apple-converted-space"> </span>return std::bit_cast<int>(n);</div><div class="">}</div><div class="gmail_quote"><br class=""></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 class=""></div><div class="gmail_quote"><br class=""></div><div class="gmail_quote">B four() {</div><div class="gmail_quote"> <span class="Apple-converted-space"> </span>int n;</div><div class="gmail_quote"> <span class="Apple-converted-space"> </span>return std::bit_cast<B>(n);</div><div class="gmail_quote">}</div><div class="gmail_quote"><br class=""></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're of byte-like type, that's OK: we can copy them about and produce them from prvalue expressions.</div><div class="gmail_quote"><br class=""></div><div class="gmail_quote"><div class=""><br class=""></div><div class="">I think the above is captured by the following wording change:</div><div class=""><br class=""></div><div class="">Change in [bit.cast]p1:</div><div class=""><br class=""></div><div class="">"""</div><div class="">Returns: An object of type To. Each bit of the value representation of the result is equal to the<br class="">corresponding bit in the object representation of from. Padding bits of the To object are unspecified.<br class=""><div class=""></div></div><div class="">If there is no value of type To corresponding to the value representation produced, the behavior is<br class="">undefined. If there are multiple such values, which value is produced is unspecified.</div><div class=""><ins>A bit in the value representation of the result is indeterminate if does not correspond to a bit in the value</div><div class=""><div class="">representation of <font face="courier new, monospace" class="">from</font><span class="Apple-converted-space"> </span>or corresponds to a bit of an object that is not within its lifetime or has an indeterminate value ([basic.indet]).</div></div><div class="">For each bit in the value representation of the result that is indeterminate,</div><div class="">the smallest object containing that bit has an indeterminate value;</div></div></div></blockquote><div class=""><br class=""></div><div class="">The above sentence makes me wonder, what effect does it have on:</div><div class=""><br class=""></div><div class="">struct A { char x[4]; };</div><div class="">union B { int i; short s; };</div><div class=""><br class=""></div><div class="">A a;</div><div class="">a.x[1] = a.x[2] = a.x[3] = 0;</div><div class="">B b = bit_cast<B>(a);</div><div class=""><br class=""></div><div class="">?</div><div class=""><br class=""></div><div class=""> </div><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-style: solid; border-left-color: rgb(204, 204, 204); padding-left: 1ex;"><div dir="ltr" class=""><div class="gmail_quote"><div class="">the behavior is undefined unless that object is of unsigned ordinary character type or std::byte type.</div></div></div></blockquote><div class=""><br class=""></div><div class="">What's the intent / effect of the above?</div><div class=""><br class=""></div><div class=""> </div><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-style: solid; border-left-color: rgb(204, 204, 204); padding-left: 1ex;"><div dir="ltr" class=""><div class="gmail_quote"><div class="">The result does not otherwise contain any indeterminate values.</ins><br class=""></div><div class="">"""</div></div></div></blockquote></div></div><span style="caret-color: rgb(0, 0, 0); font-family: BookmanOldStyle; font-size: 18px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">_______________________________________________</span><br style="caret-color: rgb(0, 0, 0); font-family: BookmanOldStyle; font-size: 18px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: BookmanOldStyle; font-size: 18px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;" class="">ub mailing list</span><br style="caret-color: rgb(0, 0, 0); font-family: BookmanOldStyle; font-size: 18px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><a href="mailto:ub@isocpp.open-std.org" style="font-family: BookmanOldStyle; font-size: 18px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">ub@isocpp.open-std.org</a><br style="caret-color: rgb(0, 0, 0); font-family: BookmanOldStyle; font-size: 18px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><a href="http://www.open-std.org/mailman/listinfo/ub" style="font-family: BookmanOldStyle; font-size: 18px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">http://www.open-std.org/mailman/listinfo/ub</a></div></blockquote></div><br class=""></body></html>