std::launder and its usage in Boost

Mikhail Kremniov via Boost-users <[email protected]>
Newsgroups gmane.comp.lib.boost.user
Message-ID <[email protected]>
Hi,

I wonder, what is the Boost community's opinion of std::launder? In 
particular, of its necessity when accessing an object that was created 
via placement-new in an aligned_storage. As I can see, it's used by 
Boost.Beast in its implementation of the variant type, but not in other 
parts of Boost.
The reason I'm asking this is that I'm working on a C++14 code-base that 
uses Boost.Variant and Boost.Optional extensively (as well as other 
parts of Boost that use Variant and Optional internally). Now we're 
trying to switch to C++17 at least, and I worry whether it could 
potentially break things.

To put things into context, C++ standard states in the [basic.life] 
section that if you had an object and then created a new one in the same 
location, you can use the pointer to the old object to refer to the new 
one only if (among other things) "the new object is of the same type as 
the original object (ignoring the top-level cv-qualifiers)".

This means, as I understand it, that it's technically illegal to 
reinterpret_cast the pointer to aligned_storage to the pointer to the 
actual type of the object created via placement-new, because 
placement-new has already ended the lifetime of the aligned_storage 
object. So, implementations of Boost.Optional and Boost.Variant are 
illegal then (?). But it's been like that since C++03 and Boost worked 
fine all that time, so it looks like this UB existed only "on paper".

But C++17 then added "Note: If these conditions are not met, a pointer 
to the new object can be obtained from a pointer that represents the 
address of its storage by calling std::launder".
So now the language has the ability to deal with that UB, and a question 
arises, is it possible that compilers could start to use the UB to 
perform additional optimizations and make it a real UB?
Also, I've seen a couple of times on stackoverflow.com people saying 
that it's actually fine to reinterpret_cast the storage in C++14, but in 
C++17 it's not (they didn't explain why though).

So, can switching from -std=c++14 to -std=c++17 be a breaking change 
when using Boost? The fact that Boost.Variant and Boost.Optional don't 
use std::launder - is it an oversight or a conscious decision?

Thanks!
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.