<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><br class=""><br class=""><blockquote type="cite" class="">On Dec 14, 2018, at 3:52 PM, Chris Dumez <<a href="mailto:cdumez@apple.com" class="">cdumez@apple.com</a>> wrote:<br class=""><br class="">So to be clear, it is often not truly about using the value after it is moved. It is about expecting that the variable / member has been nulled out after moving it.<br class="">If I WTFMove() out a data member m_dataMember, I expect later on `if (m_dataMember)` to be false.<br class=""><br class=""></blockquote><div class=""><br class=""></div><div class="">I do not mean to derail the discussion about whether or not we should have our own std::optional that disengages on move. I am all for convenience. I think expecting a valid “empty” state (*) when moving out a data member is an <b class="">anti-pattern</b> and I propose that we should be using std::exchange() instead (or any code analogous to doing std::exchange()) for these cases, including the case in your original email and <b class="">especially</b> with data members as in <<a href="https://trac.webkit.org/changeset/239228" class="">https://trac.webkit.org/changeset/239228</a>>.</div><div class=""><br class=""></div><div class="">Why do I consider it an anti-pattern? See (*) and because the concept of “moving" is not spec'ed to behave like this. Here’s one reference to the spec’ed behavior and an example comparable to the one in your first email (highlighting is my own for emphasis):</div><div class=""><br class=""></div><div class="">[[</div><div class=""><div class="" style="margin: 0.4em 0px 0.5em; line-height: 1.2em; font-family: DejaVuSans, "DejaVu Sans", arial, sans-serif; font-size: 12.800000190734863px;">Unless otherwise specified, all standard library objects that have been moved from are placed in a valid but unspecified state. That is, <b class="">only the functions without preconditions, such as the assignment operator, can be safely used on the object after it was moved from</b>:</div><div dir="ltr" class="mw-geshi" style="border: 1px solid silver; border-top-left-radius: 5px; border-top-right-radius: 5px; border-bottom-right-radius: 5px; border-bottom-left-radius: 5px; padding: 1em; margin: 1em 0px; width: 55em; background-color: rgb(249, 249, 249); overflow: auto; font-size: 12.800000190734863px; font-family: DejaVuSansMono, "DejaVu Sans Mono", courier, monospace !important;"><div class="cpp source-cpp" style="line-height: normal; font-family: monospace;"><pre class="de1" style="padding: 0px; border: 0px none white; line-height: 1.2em; border-top-left-radius: 5px; border-top-right-radius: 5px; border-bottom-right-radius: 5px; border-bottom-left-radius: 5px; margin-top: 0px; margin-bottom: 0px; width: 55em; overflow: auto; font-stretch: normal; font-size: 1em; background-image: none; vertical-align: top;"><a href="http://en.cppreference.com/w/cpp/container/vector" class="" style="text-decoration: none; color: rgb(0, 48, 128); background-image: none;"><span class="kw1266">std::<span class="me2">vector</span></span></a><span class="sy1" style="color: rgb(0, 0, 128);"><</span><a href="http://en.cppreference.com/w/cpp/string/basic_string" class="" style="text-decoration: none; color: rgb(0, 48, 128); background-image: none;"><span class="kw1227">std::<span class="me2">string</span></span></a><span class="sy1" style="color: rgb(0, 0, 128);">></span> v<span class="sy4" style="color: rgb(0, 128, 128);">;</span>
<a href="http://en.cppreference.com/w/cpp/string/basic_string" class="" style="text-decoration: none; color: rgb(0, 48, 128); background-image: none;"><span class="kw1227">std::<span class="me2">string</span></span></a> str <span class="sy1" style="color: rgb(0, 0, 128);">=</span> <span class="st0" style="color: rgb(0, 128, 0);">"example"</span><span class="sy4" style="color: rgb(0, 128, 128);">;</span>
v.<span class="me1">push_back</span><span class="br0" style="color: rgb(0, 128, 0);">(</span>std<span class="sy4" style="color: rgb(0, 128, 128);">::</span><span class="me2">move</span><span class="br0" style="color: rgb(0, 128, 0);">(</span>str<span class="br0" style="color: rgb(0, 128, 0);">)</span><span class="br0" style="color: rgb(0, 128, 0);">)</span><span class="sy4" style="color: rgb(0, 128, 128);">;</span> <span class="co1" style="color: rgb(144, 144, 144);">// str is now valid but unspecified</span>
str.<span class="me1">back</span><span class="br0" style="color: rgb(0, 128, 0);">(</span><span class="br0" style="color: rgb(0, 128, 0);">)</span><span class="sy4" style="color: rgb(0, 128, 128);">;</span> <span class="co1" style="color: rgb(144, 144, 144);">// <b class="">undefined behavior if size() == 0: back() has a precondition !empty()</b></span>
str.<span class="me1">clear</span><span class="br0" style="color: rgb(0, 128, 0);">(</span><span class="br0" style="color: rgb(0, 128, 0);">)</span><span class="sy4" style="color: rgb(0, 128, 128);">;</span> <span class="co1" style="color: rgb(144, 144, 144);">// OK, clear() has no preconditions</span></pre><div class=""><span class="co1" style="color: rgb(144, 144, 144);"><br class=""></span></div></div></div></div><div class="">]]</div><div class=""><<a href="https://en.cppreference.com/w/cpp/utility/move" class="">https://en.cppreference.com/w/cpp/utility/move</a>></div><div class=""><br class=""></div><div class="">(*) What is the valid “empty” state for a type without a default constructor?</div><div class=""><br class=""></div><div class="">Dan</div><br class=""><blockquote type="cite" class="">--<br class=""> Chris Dumez<br class=""><br class=""><br class=""><br class=""><br class=""><blockquote type="cite" class="">On Dec 14, 2018, at 3:45 PM, Chris Dumez <<a href="mailto:cdumez@apple.com" class="">cdumez@apple.com</a>> wrote:<br class=""><br class=""><br class=""><blockquote type="cite" class="">On Dec 14, 2018, at 3:39 PM, Fujii Hironori <<a href="mailto:fujii.hironori@gmail.com" class="">fujii.hironori@gmail.com</a>> wrote:<br class=""><br class=""><br class="">On Sat, Dec 15, 2018 at 6:38 AM Chris Dumez <<a href="mailto:cdumez@apple.com" class="">cdumez@apple.com</a>> wrote:<br class=""><br class="">I have now been caught twice by std::optional’s move constructor. <br class=""><br class=""> I don't understand how this could be useful? Do you want to use the value after it is moved? I'd like to see these your code. Could you show me these two patches?<br class=""></blockquote><br class="">This is the latest one: <a href="https://trac.webkit.org/changeset/239228/webkit" class="">https://trac.webkit.org/changeset/239228/webkit</a><br class=""><br class=""><br class="">_______________________________________________<br class="">webkit-dev mailing list<br class=""><a href="mailto:webkit-dev@lists.webkit.org" class="">webkit-dev@lists.webkit.org</a><br class=""><a href="https://lists.webkit.org/mailman/listinfo/webkit-dev" class="">https://lists.webkit.org/mailman/listinfo/webkit-dev</a><br class=""></blockquote><br class="">_______________________________________________<br class="">webkit-dev mailing list<br class=""><a href="mailto:webkit-dev@lists.webkit.org" class="">webkit-dev@lists.webkit.org</a><br class=""><a href="https://lists.webkit.org/mailman/listinfo/webkit-dev" class="">https://lists.webkit.org/mailman/listinfo/webkit-dev</a></blockquote></body></html>