How my papers did at Kona

As of a couple days ago, the post-Kona mailing is out!

I presented three proposals at the WG21 meeting in Kona this February. Here’s their status post-Kona:

P1144R3 “Object relocation in terms of move plus destroy”

A.k.a. “trivially relocatable.”

I presented this paper to EWGI and there was some discussion. No straw polls were taken. EWGI wants to see it again.

Based on some hallway discussions with Jens Maurer and Richard Smith, I am no longer so worried about the core-language object-lifetime issues with P1144 (a.k.a. “it works but it’s undefined behavior”). The conclusion of these discussions was that it suffices to define a “magic” library function, which P1144R3 calls std::relocate_at(src, dst). Unlike Pablo’s N4158, this magic library function is not supposed to be a customization point! It’s more like a cross between memcpy and std::launder (and Richard’s std::bless that was just adopted in Kona), but it’s not literally expressible as any combination of those three. Anyway, we just expose that magic relocate_at library function, and then vendors or end-users can use that function to do their relocations of trivially relocatable objects.

In practice, relocate_at could be implemented as a very thin wrapper around an out-of-line memcpy. We put the definition in some other translation unit so that the compiler cannot look into it and see that it’s “just” copying bytes.

Similarly, P0593R3 std::bless can be implemented as a very thin wrapper around an out-of-line no-op: the compiler cannot look into it and see that it doesn’t placement-new anything, so the compiler must assume that it might placement-new something into the address it returns, which means that even if there were no object at that address before the call to bless, the compiler must assume that there might be an object there after the call.

And of course vendors of C++ implementations are also permitted to do anything they want under the as-if rule; which means that in practice I do not expect any STL vendors to actually make calls to std::relocate_at. They will probably make calls to memcpy, and coordinate with their respective compiler vendors to ensure that memcpy Does The Right Thing for trivially relocatable types.

The other big change to P1144R3 compared to P1144R2 is that I have decided that I really want to be able to optimize vector<string>::insert and vector<string>::erase. When we insert or erase in a vector, we have to shift all the subsequent elements left or right. For trivially relocatable types, this ought to be done with a single memmove. However, the operation being replaced by the memmove in this case is not a bunch of paired constructs and destroys; it’s a “domino chain” of a bunch of move-assignments that finishes up with a single destroy. We replace that chain of assignments with a single destroy up front, followed by a memmove.

In order to give vector the freedom to do this optimization, we need to ensure that a trivially relocatable type’s move-assignment operator never does anything crazy. Therefore, P1144R3 proposes that a type without the [[trivially_relocatable]] attribute should be considered trivially relocatable only if it defaults all of its special member functions, including the assignment operators and the copy constructor in addition to the move constructor and destructor. If you define any of these special member functions, and you want your type to be trivially relocatable, you’ll have to use the attribute. However, it remains true that I don’t expect much user code ever to use the attribute. The Rule of Zero still applies. Use Rule of Zero, get trivial relocatability for free (whenever possible).

P1155R2 “More implicit moves.”

A.k.a. “fixing return x; to Do The Right Thing all the time.”

I presented this paper in EWG, and it was overwhelmingly approved for C++2a. Exciting news!

There is no new revision of P1155 in the post-Kona mailing. The wording in P1155R2 is the wording that’s going to be considered by CWG at the next meeting.

My further proposal to handle assignment operators specially was discussed by EWG in the same discussion, but the room’s consensus was generally against trying to move that piece forward. Catching pessimizations like return x /= y; will stay the domain of opt-in compiler diagnostics and human eyeballs.

P1154R2 “Type traits for structural comparison.”

A.k.a. “has_strong_structural_equality_v<T>.”

I was absent for the discussion of this paper in LEWG. (Thanks to Jeff Snyder for presenting and for telling me how it went.) The paper arrived in Kona with seven type-traits — one for each possible comparison category, plus one — and left LEWG chopped down to just the single trait has_strong_structural_equality_v<T>. Thanks to Barry Revzin’s pretty amazingly productive work on operator<=>, the notions of “structural comparison” and comparison category are no longer orthogonal, and in fact it’s possible to make a type with strong structural equality without giving it an operator<=> at all. So there’s just the one trait now, and it’s moving along to LWG wording review as part of Barry’s latest omnibus paper P1614R0 “The Mothership Has Landed: Adding <=> to the Library.”

I did put a new revision of P1154 in the post-Kona mailing, but I believe it’s already obsolete. LWG will consider the identical wording that is now part of P1614R0.

Posted 2019-03-20