On 2/18/22 19:36, Peter Dimov via Boost wrote:
Andrey Semashev wrote:
What std::launder is intended to be is a fence for compiler speculations as to the possible value in the dereferenced location. That is, in the following example:
alignas(int) unsigned char storage[sizeof(int)]; int* p1 = new (storage) int(1); float* p2 = new (storage) float(2.0f); int* p3 = new (storage) int(3); std::printf("%d\n", *p1);
the program is allowed to print 1...
I don't think it is. The "will automatically apply to the new object" clause applies (even in its C++14 form) and all its requirements seem to be met. https://eel.is/c++draft/basic.life#8
The requirement "o1 and o2 are of the same type" is not satisfied, as the types int and float are different. Yes, you eventually create an int in the same storage, but I don't see where the standard requires this exemption rule to work across creation of an object of an incompatible type. Basically, my understanding is that whenever the pointer stops pointing at an object that it used to point to, you need to use std::launder on it. The only exception is construction of a transparently replaceable object an that location, which isn't the case above.