<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
span.EmailStyle18
        {mso-style-type:personal-reply;
        font-family:"Calibri",sans-serif;
        color:windowtext;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri",sans-serif;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal">   The LLVM codebase is designed with having exceptions disabled in mind. In such a world, having noexcept everywhere is just noise (“we don’t throw exceptions, so everything is noexcept! yay!”). Furthermore, we provide a CMake build flag
 to enable exceptions with the intention that user libs with exceptions enabled would link with LLVM and that user lib exceptions would flow through LLVM. If people start adding noexcept everywhere in order to please std::vector, then you will start seeing
 crashes.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">  Since the LLVM codebase largely pretends that exceptions don’t exist, I don’t think it should do anything that will change what actually happens in the presence of exceptions. If this means that we prefer llvm::SmallVector to std::vector
 for performance reasons, then I say “so be it”.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Thanks,<o:p></o:p></p>
<p class="MsoNormal">   Christopher Tetreault<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><b>From:</b> llvm-dev <llvm-dev-bounces@lists.llvm.org> <b>On Behalf Of
</b>James Y Knight via llvm-dev<br>
<b>Sent:</b> Wednesday, December 2, 2020 9:52 AM<br>
<b>To:</b> Chris Lattner <clattner@nondot.org><br>
<b>Cc:</b> LLVM Dev <llvm-dev@lists.llvm.org><br>
<b>Subject:</b> Re: [llvm-dev] RFC: [SmallVector] Adding SVec<T> and Vec<T> convenience wrappers.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<div>
<p class="MsoNormal">On Wed, Dec 2, 2020 at 12:05 AM Chris Lattner <<a href="mailto:clattner@nondot.org">clattner@nondot.org</a>> wrote:<o:p></o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<div>
<div>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<div>
<p class="MsoNormal">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:<o:p></o:p></p>
</div>
<div>
<div>
<div>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<p class="MsoNormal">Can you spell this out for me?  Why do we need noexcept if we’re building with -fno-exceptions?  What is going on here?<o:p></o:p></p>
</div>
</div>
</div>
</blockquote>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Sure. It's a bit convoluted. Here's my understanding:<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">First, here's why std::vector has this behaviour:<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">- std::vector grow operations need to transfer their existing elements over to the new storage.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">- The grow operations are usually required to meet the "strong exception guarantee": if something throws, this function has no effect.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">- 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).<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">- 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).<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">- 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.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Second, here's why the behaviour doesn't change when -fno-exceptions:<o:p></o:p></p>
</div>
<div>
<div>
<p class="MsoNormal">- -fno-exceptions does NOT imply `noexcept` (maybe it should?, but it doesn't).<o:p></o:p></p>
</div>
</div>
<div>
<p class="MsoNormal">- 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).<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">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<o:p></o:p></p>
</div>
</div>
</div>
</blockquote>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">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.<o:p></o:p></p>
</div>
</div>
</div>
</blockquote>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">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...<o:p></o:p></p>
</div>
</div>
</div>
</div>
</body>
</html>