2 ms·
I don't think that get() needs to launder that pointer. The object of type T is constructed only once in the storage provided by an array of bytes.
by protomolecule 3y ago
I don't think that get() needs to launder that pointer. The object of type T is constructed only once in the storage provided by an array of bytes.
- LegionMammal978 3y agoIt doesn't really matter how many times the T is constructed: the pointer resulting from "new" points to the T object, but the pointer from accessing the member just points to the byte array, and the latter cannot be turned into the former without std::launder().
- protomolecule 3y agoI don't think you are right here. std::launder addresses a specific situation: when an object is replaced by another object of the same type but compiler doesn't know that the first object's lifetime has ended and the same address points to a different object. In this case compiler may still use cached values of constant or reference fields of the dead object or its vptr. In this case the byte array merely provides storage for an object of type T created by the placement new operator and that object is never replaced by anything. The lifetime of the byte array itself doesn't end when a nested object is created.
- LegionMammal978 3y agoThat's one of the situations for std::launder(). (However, in most cases where the new object has exactly the same type, C++20 has made laundering unnecessary with its 'transparently replaceable' criterion.) Yet the other situation is precisely this one [0] [1]. The byte array does provide storage for the T, but a pointer to the byte array is not a pointer to the T. You need to launder the pointer to get from the former to the latter. Such are the rules when you're bound as strictly to type-based aliasing as standard C++ is. (Not that any real compiler is nearly as strict about byte arrays in practice: if they were, then many Unix networking APIs would be practically unusable. Indeed, people care about it so little that Linux is happily adding new syscalls that write data into variable-length buffers and expect the user to arbitrarily cast them back into structs.) [0] https://en.cppreference.com/w/cpp/utility/launder#Notes https://en.cppreference.com/w/cpp/utility/launder#Notes [1] https://stackoverflow.com/a/39382728 https://stackoverflow.com/a/39382728
- protomolecule 3y agoYou are right, thank you for taking time to explain.