Из них я получаю std::span<const std::byte>. Правильно ли использовать std::byte только для того, чтобы потом сделать над std::byte* reinterpret_cast<const my_struct*>? Как это с алиасингом работает (вроде именно из-за него придумали std::byte вместо uint8_t)?
Reinterpret тут не избавит от ub
Ладно. Какое здесь UB?
Я читаю через асинхронный WinApi во временный буффер std::vector<std::byte>. Функция чтения из сокета/файла возвращает std::span<const std::byte> на этот буффер. Потом я его кастую через reinterpret_cast к своей POD-структуре (несколько int'ов, потом 255 char'ов, и т.д.) у которой выключено выравнивание. Где здесь может быть UB и сгенерирует ли компилятор оптимальный код с учетом алиасинга std::byte?
Вроде ub быть не должно
https://en.cppreference.com/w/cpp/language/reinterpret_cast Performing a class member access that designates a non-static data member or a non-static member function on a glvalue that does not actually designate an object of the appropriate type - such as one obtained through a reinterpret_cast - results in undefined behavior
В моей ситуации как понять, что я указываю на не-объект? С учетом того, что она тривиально копируется, создается и уничтожается.
When it is needed to interpret the bytes of an object as a value of a different type, std::memcpy or std::bit_cast (since C++20)can be used
То есть в C++20 вместо reinterpret_cast надо использовать std::bit_cast, правильно?
это везде так нужно делатьт
До C++20 вроде нет std::bit_cast
С двадцатого стандарта можно. Здесь как-то спрашивал со ссылкой на утвердившее новые правила предложение (если желаете разобраться).
В случае вектора мне не так очевиден ответ. Я помню гарантии на локальные массивы, malloc и new. Но наверное, можно сказать что нам известен эффект дефолтного аллокатора, который обязан вызвать new и таким образом правило неявного создания объектов сработает.
Хотя стоп, вектор же не может создать массив байт. Он их создает по одному. Кажется опять все разваливается.
Стандартный аллокатор гарантированно начинает лайфтайм массива, после чего применяется упомянутое правило о лайфтайме массивов ord-char-type/std::byte.
Кажется я перестал понимать текущую модель памяти плюсов. Спасибо за ссылку.
Все эти нововведения проистекают из [p0593r6] и ретроактивно возвращают миллионам и миллионам строк кода статус C++--программ позволяют zero-overhead десериализацию.
P0593R6: Implicit creation of objects for low-level object manipulation (by Richard Smith, Ville Voutilainen) (2020-02-14) (Related: GitHub issue)
Для чего это задумывалось я понимаю. Но формулировка создает array object, не создавая элементы массива меня вводит в ступор. Видимо придется еще раз перечитать пропозал.
Может, сразу читать в вектор структур?
Этот код читает разные структуры. Которые, в зависимости от некоторого заголовка (который тоже структура, да) могут вызывать дальнейшее чтение разных структур. А ещё я сомневаюсь, что OVERLAPPED структура (асинхронный ввод/вывод в винде) начинает лайфтайм (это вроде просто запись в буффер в памяти по указанному адресу из ядра).
Формально говоря, в данном случае UB условный, ибо компилятор на практике не докажет, что по другую сторону сискола никто не начинает лайфтайм
Обсуждают сегодня