}; };
struct Y: X{ void virtual m() { ... }; };
static_assert(sizeof(X) == sizeof(Y));
X x[2];
auto ptr = reinterpret_cast<char *>(&x[0]);
new(ptr)Y();
когда делаю x[0].m(), ругается санитайзер, хотя всё работает ОК.
member call on address 0x7fffc2422cb8 which does not point to an object of type ...
Подскажите, тут ub? Что можно сделать, чтобы не ругался? Спасибо.
чтобы не ругалось можно не писать такой код например
мне байтики надо экономить. Ещё варианты есть?
Создаётся объект поверх существующего и не удаленного, как минимум
ок, удалить можно. Это решит проблему?
а какой санитайзер ругается?
Так нельзя, да. Время жизни x (двух элементов) не завершено.
Стоит попробовать. Правда, когда массив будет удаляться, он вызовет не тот деструктор и всё сломается. И вообще для примера тут массив не нужен.
Отмывать нужно обязательно, поскольку правило для transparently-replaceable нарушается. Если деструктор X будет нетривиальным - все взорвется в нескольких местах (1, 2).
А интересно std::any реализовать с фиксированным внутренним буффером под объект может лучше будет 🤔
Он же тут просто метод X вызовет в любом случае нет?
В оригинальном коде с ub, точного ответа нет. Например кажется может сработать девиртуализация, которая проигнорирует vtbl.
потенциально много чего может быть
Вероятно. Я про конечный (предположительно корректный) вариант)
struct X{ void virtual m() { ... }; }; struct Y: X{ void virtual m() { ... }; }; static_assert(sizeof(X) == sizeof(Y)); alignof(X) std::byte storage[sizeof(X) * 2]; auto y = new(&storage[0]) Y(); auto x = new(&storage[0] + sizeof(X)) X(); А вот так подойдёт?
Обсуждают сегодня