<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Dec 2, 2020 at 9:52 AM James Y Knight via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a>> wrote:<br></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"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Dec 2, 2020 at 12:05 AM Chris Lattner <<a href="mailto:clattner@nondot.org" target="_blank">clattner@nondot.org</a>> wrote:<br></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><div><blockquote type="cite"><div>On Dec 1, 2020, at 4:07 PM, Duncan P. N. Exon Smith <<a href="mailto:dexonsmith@apple.com" target="_blank">dexonsmith@apple.com</a>> wrote:</div><div><div><div><blockquote type="cite"><div><div><br><div>Can you spell this out for me?  Why do we need noexcept if we’re building with -fno-exceptions?  What is going on here?</div></div></div></blockquote><br></div><div>Sure. It's a bit convoluted. Here's my understanding:</div><div><br></div><div>First, here's why std::vector has this behaviour:</div><div>- std::vector grow operations need to transfer their existing elements over to the new storage.</div><div>- The grow operations are usually required to meet the "strong exception guarantee": if something throws, this function has no effect.</div><div>- If move operations throw, you can't provide this guarantee unless you copy (you can't move back the elements that have been half-moved over, in case another exception is thrown; but if it was just a copy, the original storage still has the elements safely unmodified).</div><div>- There's a caveat / carve out, that if T cannot be copy-constructed AND T's move constructor is not noexcept, then the guarantee is waived (since there's no way to implement it).</div><div>- Implementation is to call std::move_if_noexcept (<a href="https://en.cppreference.com/w/cpp/utility/move_if_noexcept" target="_blank">https://en.cppreference.com/w/cpp/utility/move_if_noexcept</a>), which moves if it's a noexcept operation, or if T is not copy-constructible.</div><div><br></div><div>Second, here's why the behaviour doesn't change when -fno-exceptions:</div><div><div>- -fno-exceptions does NOT imply `noexcept` (maybe it should?, but it doesn't).</div></div><div>- This is implemented by detecting via SFINAE whether something is `noexcept` (maybe std::vector::resize/push_back/etc should have a special case? but that's controversial).</div><div><br></div><div>IMO, until all the C++ standard libraries and host compilers that we support being built with will consistently use std::move on grow operations in std::vector in -fno-exceptions mode, we should only use std::vector when we absolutely have to. It's not designed for -fno-exceptions codebases</div></div></div></blockquote><div><br></div><div>Wow, thank you for the great explanation.  I agree with you that this seems like a pretty credible reason why we can’t depend on every host std::vector to do what we need, so we should use something like an llvm::Vector.</div></div></div></blockquote><div><br></div><div>I strongly disagree here. Not wanting to bother to add 'noexcept' to user-defined move-constructors is a poor justification for switching to a different vector type. Perhaps there are <i>other</i> reasons which might justify avoiding std::vector, but not that...</div></div></div></blockquote><div><br></div><div>It isn't clear that it makes sense to just add "noexcept" everywhere in our codebase just because we build with -fno-exception. Should we decorate every single API everywhere? Which one actually matters?</div><div>Why is it better to add these everywhere in the codebase rather than just aligning our data-structure? (since there is also the `SmallVectorImpl` issue of function arguments...).</div><div><br></div><div>-- </div><div>Mehdi</div><div><br></div></div></div>