Ответ 1
Предупреждение абсолютно оправдано. Разложившийся указатель на data
делает не ссылкой на объект типа int
, а его литье не меняет этого. См. [basic.life]/7:
Если после окончания срока службы объекта и до хранения который занятый объект повторно используется или освобождается, новый объект созданный в месте хранения, в котором находился исходный объект, a указатель, указывающий на исходный объект, ссылка, ссылка на которую к исходному объекту, или имя исходного объекта будет автоматически ссылаются на новый объект и, как только время жизни новый объект запущен, может использоваться для управления новым объектом, , если:
(7.1) - [..]
(7.2) - новый объект имеет тот же тип, что и исходный объект (игнорируя cv-квалификаторы верхнего уровня),
Новый объект не является массивом char
, а int
. P0137, который формализует понятие указания, добавляет launder
:
[Примечание: если эти условия не выполняются, указатель на новый объект может быть получен из указателя, который представляет адрес его путем вызова
std::launder
(18.6 [support.dynamic]). - конечная нота ]
т.е. ваш фрагмент можно исправить следующим образом:
std::cout << *std::launder(reinterpret_cast<int*>(data));
.. или просто инициализируйте новый указатель из результата размещения new, который также удаляет предупреждение.