std::launder и strict aliasing
Вообщем у меня в голове возникла небольшая путаница с strict aliasing и std::launder. По стандарту следующий код является UB:
void foo(int x)
{
float *p = reinterpret_cast<float *>(&x);
*p = 1.0f;
std::cout << x << std::endl;
}
Но будет ли UB если использовать std::launder?
void foo(int x)
{
float *p = reinterpret_cast<float *>(&x);
*p = 1.0f;
std::cout << *std::launder(&x) << std::endl;
}
Фактически, на современных версиях компиляторов (по крайней мере у меня) обе версии кода отработают правильно, но первая это гарантированно UB, а со второй у меня возникли сложности с пониманием.
На многих форумах (и в некоторых статьях) второй код приводится как пример работы std::launder, но разве это все еще не UB по формальным причинам?
Ответы (1 шт):
std::launder не для этого (тут он не убирает UB).
Он нужен когда указатель на правильный тип, но сам указатель был получен нелегальным путем.
Самый популярный пример:
alignas(MyClass) char buffer[sizeof(MyClass)];
::new((void *)buffer) MyClass;
Вот если теперь сделать reinterpret_cast<MyClass *>(buffer) - то результат нужно обработать std::launder, иначе будет UB.
А если сохранить возвращаемое значение new - указатель можно использовать как есть.