170 похожих чатов

Интерпретирует сырые данные как структуру, не?

12 ответов

16 просмотров

https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2590r2.pdf We further added a precondition missing in [P0593R5] stating that the passed-in storage is suitably aligned for the type of object being created.

Alexander Petrov
https://www.open-std.org/jtc1/sc22/wg21/docs/paper...

Из объяснения я не понял, почему reinterpret_cast приведет к UB, а lifetime_as нет? Будто в С++20 поменялись какие-то базовые концепции, есть ли какой-то ёмкий обзор? Зачем компилятору знать, кто владеет объектом или кто его инициализировал, еcли тот well-aligned и POD?

MT Radio Arkadio
Из объяснения я не понял, почему reinterpret_cast ...

Кстати, хороший вопрос, как правильно поступить в такой ситуации: Хочу писать и читать обычный wav файл, он состоит из заголовка и данных, заголовок представляется структурой, я заполнил поля структуры и записал в файл как массив байт через reinterpret_cast<std::byte* > ( ) Читаю так же. Вопрос - а как надо правильно в С++ ?

MT Radio Arkadio
Из объяснения я не понял, почему reinterpret_cast ...

А тут все сложно, запутанно и просто одновременно. Имхо со времен введения понятия стрикт-алиасинга и оптимизации на этом деле компилятор слишком агрессивно начинает это дело оптимизировать (выкидывать код) из-за чего reinterpret_cast вроде как низя(не рекомендуется) и вводят bit_cast https://en.cppreference.com/w/cpp/numeric/bit_cast Также для защиты планеты в стандарте запрещают смешивание типа на unione - мол записал поле foo вот и юзай только его, а иначе UB. Даже если ты даешь гарантию, выравнивание и т.п... боль и страдание Да понятно что в стандарте имели ввиду что сложные типы(не тривиальные) с виртуальностью, атомиками и бла бла бла в union-е создал, а юзаешь поле которое не сном не духом про эту сложность, вывод, ты - идиот(ктож спорит), но под это дело попало и то что записав 4х байтный инт, байтами ты не можешь прочитать его как инт, читай блин байты! тот же Clang орет мол ай ай так делать низя. из-за чего проверить эндианс через union считается UB (хотели как лучше...) Вплоть до юзай bit_cast или сам memcpy пиши, мол компилятор поймет и оптимизирует это дело. будет быстро не переживай. то что ты для этого обмазался лишним кодом, ну UB же, сам виноват. Потом вводят lifetime_as который как раз и делает то что делали программисты на union-е. мол чувак, там лежат байты, я хочу чтоб ты без всякого UB и мега конструкторов и бла бла бла, просто понял что это вот эта штука(как и откуда эти байты не важно), доверься мне я знаю что я делаю. Поэтому в этом предложении и требуют чтоб там было все выровнено и лежало так как и должно! Я задал вопрос выше, а какое поле будет активным если мы скажем что вот эти байты вот это lifetime_as<same_union>? Полухин говорит, что вроде как любое! Тем самым lifetime_as вроде как легализует смешивание типа на unione. Возможно еще будут уточнения, но если это так, может и не нужен был lifetime_as, а надо было убрать из стандарта UB на чтение не активных полей union. Да требовать, что программист понимает что он делает, да он должен гарантировать выравнивание, паддинги, упаковку и все такое. Если программист не дал этих гарантий ну он в рантайме получит тыквы в виде HardFault или из-за выравнивания BusFault и т.п НО он это получит и из-за lifetime_as, да даже если сделает memcpy если сделает ее в не правильно выровненную память. PS. gcc ну по крайней мере собранный ARM-ом для baremetal игнорит UB для union что радует.

Stas Koynov
А тут все сложно, запутанно и просто одновременно....

спасибо за такое полное разъяснение, картина становится понятнее =) Ты прям вот ответил про то, про что я спросил, как вышло и что делать =) В принципе, то, что теперь это UB, и даже может быть какой-нить санитайзер научится про это давать полезную информацию, выглядит из твоего объяснения хорошей штукой, поскольку понижает шанс выстрелить себе в ногу случайно. Но вот все базы кодов, в том числе современных, высоконагруженных и крутых проектов, в лучшем случае переползли на С++11\14, а некоторые еще не могут сделать и этого (например, если заявлена поддержка старых никсовых ядер, идущих с gcc 4.4). И все они довольно активно пользуются вещами, вроде reinterpret_cast, который раньше был ОК, а теперь UB. Т.е. огромные тонны кода, оказывается, непереводимы на более современные компиляторы, т.к. те потеряли обратную совместимость, как минимум вот этим вот новым правилом про UB, и я не удивлюсь, если чем-то еще тоже. Как предполагается действовать в этом случае? =)

MT Radio Arkadio
спасибо за такое полное разъяснение, картина стано...

да хз как действовать, если юзать для каждого чиха memcpy или bit_cast в надежде что все айс. ну наверное. и идея то понятна, сделать код быстрее. ведь у нас же типизированный язык. как указатель на char может поменять вот этот инт? ну по идее никак(стрикт алиасинг). но из-за низкоуровневых штук, смешиваниях типов на union-e получается можно. тут как раз и вводят мол давайте сделаем это UB и все... сделать то сделали. и пошли ситуации, даже не на бареметалл а тут в биг системе. ну буфер у тебя все айс. выровнил ты. структура у тебя упакованная. прилетела она тебя (байтами) через сетку. а по всем стандартам не можешь ты мацать ее. не можешь и все. лайфтайм же не начинался, тут на помощь и пришел этот lifetime_as, но из-за него я могу обойти UB для union-a? эмм тут палка о двух концах. либо lifetime_as для union-a запретят. либо скажут делать switch case на каждое поле для lifetime_as. ХЗ я сам не знаю. пока тупо юзаю в эмбедете для протокольных вещей тупо union да даю гарантию на то что буфер выровнен. если данные смешанные, структуры упаковываю (для них компилятор сам инты читает байтами, если видит, что начальное выравнивание не кратно 4 и т.п). Да приходиться лезть в асм код, смотреть а все ли айс. Так что да, ждем развития и пояснений на счет lifetime_as.

MT Radio Arkadio
спасибо за такое полное разъяснение, картина стано...

"Новым"? Это правило уже лет цать существует :) start_lifetime_as() - долгожданная "официальная" лазейка

Stas Koynov
А тут все сложно, запутанно и просто одновременно....

Потому что компиляторы привыкли к тайп паннингу через юнионы, и не жрут его. Только кланг жрет и юнионы, но отключается через параметр -fstrict-aliasing

Есть: это UB было всегда

Alexander Karaev
Есть: это UB было всегда

т.е. всегда reinterpret_cast участка памяти well-aligned в POD структуру — UB? Не знал, это очень частый и везде используемый паттерн же. Тогда вопрос: начиная с какого компилятора этот извечный UB стандарта становится проблемой для разработчика, т.к. раньше нигде это проблемой для разработчика не было. gcc 2.9.2 (о да, такое тоже иногда приходится поддерживать) — вроде бы нет gcc 4.1.2 — вроде бы нет gcc 4.4.7 — вроде бы нет gcc 4.8.2 — вроде бы нет gcc 8.0+ — ?

Sergey Anisimov
С C++20 - нет. См. [p0593r6].

P0593R6: Implicit creation of objects for low-level object manipulation (by Richard Smith, Ville Voutilainen) (2020-02-14) (Related: GitHub issue)

Похожие вопросы

Обсуждают сегодня

Коллеги, я тут для личных нужд пошел ставить MQTT сервер, пощупал mosquitto, но ужаснулся отсутствию такой банальности, как HTTP API для посмотреть список топиков. А тут что,...
Maksim Lapshin
13
Всем привет! Имеется функция: function IsValidChar(ch: UTF8Char): Boolean; var i: Integer; ValidChars: AnsiString; begin ValidChars := 'abcdefghijklmnopqrstuvwxyzABCDE...
Евгений
44
#include <stdio.h> #include <stdlib.h> #include <time.h> void mass_first_generate(int mass[5][7]) {     for (int N = 0; N < 5; N++) {         for (int A = 0; A < 7; A++) {   ...
Чувак
6
Всем привет! Решаю 99 OCaml Problems и столкнулся со следующей проблемой (прошу палками не забивать, я OCaml практически не трогал до этого момента): open OUnit2 let create_...
К|/|pи/\/\ 6е3yглbIи
2
https://www.linkedin.com/posts/ugama-benedicta-kelechi-codergirl-103041300_mobiledevelopment-fluttertraining-handsonlearning-activity-7263445699227254784-IdHB?utm_source=share...
CoderGirl
16
Ну вот просто даже давайте вот как. Какой нибудь конкретный кейс, можете в пример привести, где бч работает и приносит прикладную пользу, а не просто что бы было? Не крипту.
Alexander Andreev
22
возможно ли как-то передать в электрон или таури медиа поток с рендера 2д движка? двиг запускается как dll, а дальше надо как-то отправлять рендер кодировать не подходит, зр...
Kyle Nekto
7
Точно, оно. У тебя там имена потоков выставляются?
Александр (Rouse_) Багель
11
Помогите пожалуйста. Делаю систему плагинов. Проблема сейчас в такая: плагины загружаются в основном потоке. FLibHandle := SafeLoadLibrary(FFileName) Но нужно еще выполнить фу...
Илья 🤣
10
объясните пожалуйста, почему функция не работает должным образом? вроде должно брать активное окно сравнивать его размер с размером экрана, и если есть совпадение = true прове...
JF
12
Карта сайта