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 шт):

Автор решения: HolyBlackCat

std::launder не для этого (тут он не убирает UB).

Он нужен когда указатель на правильный тип, но сам указатель был получен нелегальным путем.

Самый популярный пример:

alignas(MyClass) char buffer[sizeof(MyClass)];

::new((void *)buffer) MyClass;

Вот если теперь сделать reinterpret_cast<MyClass *>(buffer) - то результат нужно обработать std::launder, иначе будет UB.

А если сохранить возвращаемое значение new - указатель можно использовать как есть.

→ Ссылка