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

#Вопрос к знатокам стандарта. Тут есть нарушение strict aliasing? uint8_t buffer[8]

= {1, 1, 1, 1, 0, 0, 0, 0};

uint32_t *p = reinterpret_cast<uint32_t *>(buffer);
printf("0x%x\n", *p);

32 ответов

10 просмотров

Зависит от того какой настоящий тип у uint8_t. Если один из стандартной тройки char, unsigned char, byte, вроде все ок.

Да, здесь прямое нарушение, как минимум дважды

magras
Но не правил алиасинга.

Нет, и правил алиасинга, именно что можно алиасить чаром всё что угодно, но не в обратную сторону. Здесь можно было бы поправить через использование memcpy, однако мы должны были бы копировать часть буфера, по размеру равную uint32_t

Liber Azerate
Нет, и правил алиасинга, именно что можно алиасить...

Возможно я ошибаюсь, но буфер char'ов всегда можно было использовать под любой тип. Да, объект в этом буфере нужно в начале создать и в примере выше есть проблемы с лайфтамом. Но мне сложно поверить что там есть проблема с алиасингом.

Liber Azerate
Нет, и правил алиасинга, именно что можно алиасить...

тривиальные типы и структуры вроде можно рентерпреткастить в/из char. Но не помню наверняка

Liber Azerate
Нет, и правил алиасинга, именно что можно алиасить...

Вопрос можно поставить даже проще: как реализовать std::vector если нельзя скастить массив char в массив T?

magras
Вопрос можно поставить даже проще: как реализовать...

Скастить-то можно, но не так https://eel.is/c++draft/basic.lval#11

Liber Azerate
Скастить-то можно, но не так https://eel.is/c++dra...

Так это проблема с лайфтамом, а не алиасингом.

magras
Так это проблема с лайфтамом, а не алиасингом.

Нет, здесь попытка прочитать значение через несоответствующий тип, нарушение strict aliasing. Чётко по пункту стандарта

Liber Azerate
Нет, здесь попытка прочитать значение через несоот...

Окей, я сформулирую свою мысль по-другому. В этом примере нет UB: char* buf = new char[sizeof(T)]; // assuming here that T has no overalignment new(buf) T; T* p = reinterpret_cast<T*>(buf); // я специально разделил placement new и каст *p; // read or write T

Liber Azerate
В первой части, до каста, нет

Почему после каста UB появляется? После placement new по адресу buf уже есть объект с типом T.

magras
Окей, я сформулирую свою мысль по-другому. В этом ...

Хотя я не прав и адрес возвращенный placement new может отличаться от reinterpret'а из-за особенностей new. Но это опять же не проблема алиасинга. upd: Это касается только создания массивов. Так как placement new у меня создает объект, а не массив, здесь проблемы не должно быть.

magras
Окей, я сформулирую свою мысль по-другому. В этом ...

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

Alexander Tulikov
Здесь нет UB, потому что есть динамический тип и с...

Да, но изначальный вопрос был только о алиасинге, а не UB в целом.

magras
Да, но изначальный вопрос был только о алиасинге, ...

Нет UB из-за strict aliasing violation потому, что динамические типы совпадают* А там есть

Liber Azerate
Нет UB из-за strict aliasing violation потому, что...

Ладно, предлагаю постановить что там есть UB по многим причинам: 1. aliasing 2. lifetime 3. alignment (возможно я еще что-то забыл) Я бы сказал, что нарушение lifetime было первично и если исправить его (как в моем примере) проблемы с алиасингом не будет. Но видимо это зависит от точки зрения.

magras
Ладно, предлагаю постановить что там есть UB по мн...

Согласен. Впрочем, используя type punning мы могли бы обойти нарушение strict aliasing и без решения каких-либо проблем с lifetime. Точнее, у нас бы их попросту не было

Liber Azerate
Согласен. Впрочем, используя type punning мы могли...

Это ведь про нововведение 20го стандарта? Там был список функций, которые такое делают: malloc, memcpy и прочие, но я не уверен, что оно неявно создает типы в обычных массивах на стеке. Пойду поищу пропозал.

magras
Это ведь про нововведение 20го стандарта? Там был ...

Вообще, в C++20 добавился bit_cast, насчёт memcpy, как мне кажется, это было и до 20-го стандарта

magras
Это ведь про нововведение 20го стандарта? Там был ...

> We propose that at minimum the following operations be specified as implicitly creating objects: > * Creation of an array of char, unsigned char, or std::byte implicitly creates objects within that array. Таки должно работать с обычными массивами. Если что это из [P0593R6].

magras
> We propose that at minimum the following operati...

P0593R0: What to do with buffers that are not arrays, and undefined behavior thereof? (by Ville Voutilainen) (2017-02-05) (Related: GitHub issue) P0593R1: Implicit creation of objects for low-level object manipulation (by Richard Smith, Ville Voutilainen) (2017-10-16) (Related: GitHub issue) P0593R2: Implicit creation of objects for low-level object manipulation (by Richard Smith) (2018-02-11) (Related: GitHub issue) P0593R3: Implicit creation of objects for low-level object manipulation (by Richard Smith) (2019-01-18) (Related: GitHub issue) P0593R4: Implicit creation of objects for low-level object manipulation (by Richard Smith) (2019-06-17) (Related: GitHub issue) P0593R5: Implicit creation of objects for low-level object manipulation (by Richard Smith) (2019-10-07) (Related: GitHub issue) P0593R6: Implicit creation of objects for low-level object manipulation (by Richard Smith, Ville Voutilainen) (2020-02-14) (Related: GitHub issue)

Liber Azerate
Вообще, в C++20 добавился bit_cast, насчёт memcpy,...

Не думаю. С memcpy трюк заключался в том, чтобы скопировать данные в уже существующий объект нужного типа. По-моему на cppref в статье про bit_cast была реализация для старых стандартов использующая этот прием.

magras
Не думаю. С memcpy трюк заключался в том, чтобы ск...

Ну да, объект должен был уже существовать. Вероятно, в том примере в любом случае необходимо было решить проблему с lifetime, так или иначе

magras
Окей, я сформулирую свою мысль по-другому. В этом ...

кстати можно же делать void* ptr = operator new(16, std::align_val_t(16));

Андрей Руссков
кстати можно же делать void* ptr = operator new(16...

Мне лень было искать точный синтаксис, чтобы задать правильное выравнивание, поэтому я использовал то что new char[] имеет максимальное "обычное" выравнивание и добавил комментарий про overalignment. =)

magras
Мне лень было искать точный синтаксис, чтобы задат...

разве через new если ааллцировать то у чар будет макс выравнивание? Я думал только через malloc

magras
> We propose that at minimum the following operati...

в стандарте оно вот здесь

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

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

Anyone here suffers from unexplained aural migraines, who would be up for talking for a bit? Doesn't *have* to be aural, but I am not asking about headaches, I mean actual mi...
Martin Rys
55
Привет, нужен совет старших товарищей. Есть глобальная переменная var DefaultDataFolder:string; инициализируем DefaultDataFolder:='a:\_OUT\'; есть примитивная процедур...
Max Otto
11
Вопрос. Теоретический. Есть список команд. Команды отправляю в обработку некой функции, по очереди. Разные команды могут давать разные результаты после обработки. В зависимос...
Serjone
7
Всем вечера. Подскажите как лучше сделать. делаю на Д10 Например будет база данных на SQLite. в ней будет много таблиц. более 50шт Типа справочник. Содержать ID Name Id p...
Андрей Т 🐎
10
Я короче решил скомпилировать Nim в js, я думал он сработает как обычный транслятор. По итогу он мне создал файл с расширением js, и туда поместил кучу кода Вопрос, что это з...
𝕾𝖍𝖆𝖉𝖊 <suspense>
9
это группа токсиков или тех кто помогает?
Ибрагим
9
мы пытаемся подменить функцию, которая имеет меньше инструкций относительно функции, которой подменяем. https://www.reddit.com/r/jailbreakdevelopers/comments/w06ujy/mshookfun...
Óðinn
6
У кого-нибудь есть под рукой функция кодирования юникода, которая из фразы На русском сделает \u041d\u0430\u0020\u0440\u0443\u0441\u0441\u043a\u043e\u043c ?
Daniil Smolyakov
7
подскажите пожалуйста, как мне освободить результат записанный в переменную result? в чем проблема подскажите если МОЖЕТЕ?
Михаил Helper
28
я не магистр хаскеля, но разве не может лейзи тип конвертнуться в не-лейзи запросив вычисление содержимого прям при инициализации?
deadgnom32 λ madao
100
Карта сайта