<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Aug 26, 2020 at 11:34 AM Richard Smith via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a>> wrote:<br></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="ltr"><div dir="ltr">On Wed, 26 Aug 2020 at 10:18, Nevin Liber via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>> 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 dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr">On Tue, Aug 25, 2020 at 4:37 PM David Blaikie via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>> 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 dir="ltr"><br></div><div class="gmail_quote"><div>>From what I can tell, reading this ( <a href="https://stackoverflow.com/questions/58283694/why-is-pair-of-const-trivially-copyable-but-pair-is-not" target="_blank">https://stackoverflow.com/questions/58283694/why-is-pair-of-const-trivially-copyable-but-pair-is-not</a> ) and the C++17 spec, it just doesn't specify the copy and move assignment operators as defaulted, or say anything about their triviality, so they aren't trivial even for trivial types. Perhaps an oversight when thinking about the other complexities of when they shuold be deleted. </div></div></div></blockquote><div><br></div><div>In general, move/copy assignment cannot be defaulted for pair, because assignment of reference types has meaning:</div><div><br></div><div><font face="monospace">int i = 2;</font></div><div><font face="monospace">int j = 3;</font></div><div><font face="monospace">std::pair<int&, int> p1(i, 5); </font></div><div><font face="monospace">std::pair<int&, int> p2(j, 7);</font></div><div><font face="monospace">p2 = p1;  // j now has the value 2</font></div><div><font face="monospace"><br></font></div><div><font face="monospace"><br></font></div><div><div style="color:rgb(0,0,0)"><font face="monospace">struct A</font></div><div style="color:rgb(0,0,0)"><font face="monospace">{</font></div><div style="color:rgb(0,0,0)"><font face="monospace">    A(int& r_, int i_) : r(r_), i(i_) {}</font></div><div style="color:rgb(0,0,0)"><font face="monospace">    int& r;</font></div><div style="color:rgb(0,0,0)"><font face="monospace">    int i;</font></div><div style="color:rgb(0,0,0)"><font face="monospace">};</font></div><div style="color:rgb(0,0,0)"><font face="monospace"><br></font></div></div><div style="color:rgb(0,0,0)"><div><font face="monospace">int i = 2;</font></div><div><font face="monospace">int j = 3;</font></div></div><div><font face="monospace">A a1(i, 5);</font></div><div><font face="monospace">A a2(j, 7);</font></div><div><font face="monospace">a2 = a1;  // Compile time error - deleted copy assignment operator</font></div><div><br></div><div><br></div><div>Now,  this doesn't that pair couldn't have trivial copy/move assignment operators when it holds trivially copy/move assignable types, but I don't know how much of an ABI break this would be.</div></div></div></div></div></div></div></div></div></blockquote><div><br></div><div>Making std::pair be trivially-copyable whenever possible would affect whether std::pair is POD for the purpose of layout, which could result in an ABI break for at least any code that derives from std::pair or that contains a [[no_unique_address]] std::pair member: <a href="https://godbolt.org/z/GTvo4r" target="_blank">https://godbolt.org/z/GTvo4r</a></div><div><br></div><div>This is certainly not something we could do for the libc++ stable ABI. Maybe for the unstable ABI, but given the above change only makes layout worse, it's not clear that there would be a strong motivation. We already give std::pair trivial copy/move construction and trivial destruction whenever possible, so we can pass and return it efficiently.</div></div></div></blockquote><div><br>Interesting - so POD for the purpose of layout is... not good? or more restrictive on the layout than if not. (probably an impractical idea, but would it be reasonable then to have an attribute that says "not POD for the purposes of layout" but I guess that'd have to be cross-compiler/etc/etc... probably too much work)<br><br>What's the cost of pair having non-trivial copy assignment? More expensive vector of pair resizing (though I guess the copy ctor calls would be readily optimized away & LLVM could get that back to a memcpy anyway?)?<br><br>(the original issue with the warning could be fixed by narrowing the warning to only worry about trivial copy construction, not trivial copyability in general)<br><br>- Dave </div></div></div>