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

Нет ли тут какой-нибудь подлянки из-за того, что мы тасуем

байты внутри живого объекта?

59 ответов

130 просмотров

Единственное, я бы оперировал unsigned char, вместо uint8_t

Дмитро Цимбалюк
Почему так?

По определению strict aliasing https://en.cppreference.com/w/c/language/object

Есть: этого нельзя делать в настоящий момент.

Sergey Anisimov
См. [p1839].

P1839R0: Accessing Object Representations (by Krystian Stasiowski) (2019-08-09) (Related: GitHub issue) P1839R1: Accessing Object Representations (by Krystian Stasiowski) (2019-10-02) (Related: GitHub issue) P1839R2: Accessing Object Representations (by Krystian Stasiowski) (2019-11-20) (Related: GitHub issue) P1839R3: Accessing Object Representations (by Krystian Stasiowski, Timur Doumler) (2022-02-19) (Related: GitHub issue) P1839R4: Accessing Object Representations (by Krystian Stasiowski, Timur Doumler) (2022-03-16) (Related: GitHub issue) P1839R5: Accessing object representations (by Timur Doumler, Krystian Stasiowski) (2022-06-17) (Related: GitHub issue)

d7d1cd- Автор вопроса
Sergey Anisimov
Есть: этого нельзя делать в настоящий момент.

То есть, тасовать байты нельзя, а заполнить uint32_t через memset можно? uint32_t data = 0; memset(&data, 0x42, sizeof(data));

d7d1cd
То есть, тасовать байты нельзя, а заполнить uint32...

Заполнение через memset() - серая зона. Можно считать, полагаю, что это исключение для стандартной библиотеки. Сишное наследие слабо покрывается крестовым нормативом, обычно там просто пишут, что "контракты такие же, как в C", с пренебрежением к тому, что модели различаются.

d7d1cd- Автор вопроса
d7d1cd- Автор вопроса
Sergey Anisimov
Да.

А как тогда поменять местами байты внутри uint32_t?

d7d1cd- Автор вопроса
Aniki Hi$ok@ 🌈 Z 🐀
ручками

Вы историю вопроса читали вообще?

d7d1cd
Вы историю вопроса читали вообще?

Потенциально можете создать новый объект с таким значением.

d7d1cd- Автор вопроса
Sergey Anisimov
Потенциально можете создать новый объект с таким з...

Так а значение как получить? Ведь мне исходные данные в рантайме придут

d7d1cd
Так а значение как получить? Ведь мне исходные дан...

as_bytes можно попробовать, опять же, полагаясь на библиотечное исключение. Что примечательно, нормативное описание этих примитивов по сути означает, что осмысленно пользоваться ими нельзя. Надо бы посмотреть issue по этому поводу, наверное...

d7d1cd
Так а значение как получить? Ведь мне исходные дан...

это нужно делать аккуратно, идеально покрыть тестами, чтобы код работал как ты это задумал. А так, тут запрета нет, как обрабатывать биты, хоть массив, хоть каст в структуру, хоть onion, портянка из сдвигов

d7d1cd
А как тогда поменять местами байты внутри uint32_t...

Написать менялку через сдвиги и &, компилятор поймет и сделает все, что нужно, коротким путем.

d7d1cd- Автор вопроса
Aniki Hi$ok@ 🌈 Z 🐀
это нужно делать аккуратно, идеально покрыть теста...

В этом примере все аккуратно. Все тесты проходят. Однако это UB 😂

d7d1cd- Автор вопроса
Sergey Anisimov
См. [p1839].

Не понял из документа следующий момент в этом примере: using T = unsigned char*; int a = 0; T b = reinterpret_cast<T>(&a); // Pointer value unchanged, still // points to the int object T c = ++b; // UB, expression type differs // from element type Почему здесь UB? Мы сказали, что b - это указатель на unsigned char. Далее мы его инкрементим и его значение присваиваем другой переменной того же типа. Почему UB?

d7d1cd
Не понял из документа следующий момент в этом прим...

Выполняя реинтерпретацию мы всего лишь подправляем тип выражения: сам указатель от этого указывать на a не перестает - это тема provenance'ов и, в частности, std::launder() как раз.

d7d1cd
А как тогда поменять местами байты внутри uint32_t...

Макросами или constexpr, чтобы делегировать подтасовку на preprocessing-time/compile-time

d7d1cd
В этом примере все аккуратно. Все тесты проходят. ...

https://godbolt.org/z/h3b48TsKc вот, прячешь функцию в какой нибудь хидер и никто не заметит что ты ниггадяй, а главное ноги твоей функцией не отстрелит

Sergey Anisimov
Выполняя реинтерпретацию мы всего лишь подправляем...

в том примере даже не разыменовывается ничего выражение T c = ++b; где b и c это указатели типа T, по-моему всегда валидно, пока ++b не заходит за past-the-end

d7d1cd
В этом примере все аккуратно. Все тесты проходят. ...

https://godbolt.org/z/4jT5Ms4s8 вот, в точке вызова никто твои магические упражнения и не заметит

d7d1cd
А компилятор? 😂

а тут ты главный, чего, боишься компилятора? Ну можешь копировать побайтово сдвигом и делать без каста, но и тут компилятор не ругается, все хорошо

d7d1cd- Автор вопроса
Aniki Hi$ok@ 🌈 Z 🐀
а тут ты главный, чего, боишься компилятора? Ну мо...

После приведенных документов выглядит как наброс на вентилятор и троллинг

Vlad
в том примере даже не разыменовывается ничего выр...

> не заходит за past-the-end Но past-the-end чего?) Резюмирую пример: int i{}; reinterpret_cast<byte*>(&i) + 1; Этого уже достаточно для неопределенного поведения по определению арифметики указателей (нет подлежащего массива). Поскольку e[i] == *(e + i), с индексацией такая же проблема.

d7d1cd
После приведенных документов выглядит как наброс н...

не увидел документов касающихся типа int и его производных

Sergey Anisimov
> не заходит за past-the-end Но past-the-end чего?...

вы упускаете http://eel.is/c++draft/basic.compound#3.sentence-12

Vlad
вы упускаете http://eel.is/c++draft/basic.compound...

Уточните, что считаете релевантным там. По моим представлениям оно всего лишь про: T a[n] -> T a[n + 1]; T a -> T a[2]; (где последний элемент "гипотетический" и получать доступ к нему нельзя - только сравнивать и перемещаться)

Vlad
вы упускаете http://eel.is/c++draft/basic.compound...

А, хотя я понял, кажется, Вашу мысль здесь: Вы имеете в виду, что int i; reinterpret_cast<byte*>(&i) + 1 /* #1 */; как раз должно быть можно и в #1 результат должен указывать на past-the-end для int исключительно за счет того, что прибавляется именно единица? =) Да, формально Вы должны быть правы, в таком случае, но думаю, что это - очередная дыра в себе (поскольку адресно результат будет другим: расчет ведь по ct-типу).

Sergey Anisimov
Уточните, что считаете релевантным там. По моим пр...

так речь не о гипотетическом типе T, а о uint32_t, устройство которого нам достоверно известно. Тогда и char[] - это уб, ну мы же МОЖЕМ выйти за пределы массива

Sergey Anisimov
А, хотя я понял, кажется, Вашу мысль здесь: Вы име...

скорее всего я не прав, потому что как вы правильно заметили, формально там нет не то что массива, и но и объекта типа unsigned char

Aniki Hi$ok@ 🌈 Z 🐀
так речь не о гипотетическом типе T, а о uint32_t,...

Вы, вероятно, упускаете суть беседы. Уточните, что именно не понимаете и в чем видите здесь аналогию с char[].

d7d1cd
В этом примере все аккуратно. Все тесты проходят. ...

Главный вопрос - а нафига вручную reverse писать, есть же готовые функции.

Vlad
скорее всего я не прав, потому что как вы правильн...

Ну цитируемое должно быть справедливо, но составлять issue смысла не вижу: такие противоречия, как я понял, признаются и обрабатываются неохотно, особенно с учетом того, что с принятием 1839 (которое пока не предвидится, как я понимаю), смысл оно вовсе потеряет скорее всего.

d7d1cd- Автор вопроса
Sergey Anisimov
Есть: этого нельзя делать в настоящий момент.

Sergey, касательно этого Вашего ответа. Как описано в моем изначальном примере делать нельзя, это UB. Я переписал функцию reverse. Скажите, теперь в ней есть UB?

d7d1cd- Автор вопроса
Aleksander Spichak
ub

А где именно?

d7d1cd
А где именно?

На моменте memcpy последнего

d7d1cd- Автор вопроса
Aleksander Spichak
На моменте memcpy последнего

Вот тут: std::memcpy(&value, buff, size); ?

d7d1cd- Автор вопроса

Так, опять поломка старых знаний... Вроде как заполнять объект через memcpy можно. Тем более тривиальный тип.

d7d1cd- Автор вопроса

А если ограничить тривиальными?

d7d1cd
А если ограничить тривиальными?

я бы сказал только фундаментальными типами

d7d1cd
А если ограничить тривиальными?

Вопрос - а зачем именно через временный буфер, хочется "универсальности" ?

d7d1cd- Автор вопроса
d7d1cd
А как без него?

Битовые операции

d7d1cd- Автор вопроса
Aleksander Spichak
Битовые операции

Код будет гораздо сложнее тогда.

d7d1cd- Автор вопроса
Александр Водянников
И ???

Так а зачем, если приведенный более понятен, делает то же самое и в нем нет ub?

d7d1cd
Так, опять поломка старых знаний... Вроде как запо...

В отношении memcpy() есть всего два специальных разрешения (1, 2), которые относятся к Вашему примеру и все-таки не покрывают. В остальном, норматив ссылается на С-стандарт, который на настоящий момент описывает memcpy() так: > The memcpy function copies n characters from the object pointed to by s2 into the object pointed to by s1. If copying takes place between objects that overlap, the behavior is undefined. Как это транслируется в крестовую объектную модель - shrug: по моему представлению, в этом отношении объектная модель underspecified.

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

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

Господа, а что сейчас вообще с рынком труда на делфи происходит? Какова ситуация?
Rꙮman Yankꙮvsky
29
А вообще, что может смущать в самой Julia - бы сказал, что нет единого стандартного подхода по многим моментам, поэтому многое выглядит как "хаки" и произвол. Короче говоря, с...
Viktor G.
2
30500 за редактор? )
Владимир
47
а через ESC-код ?
Alexey Kulakov
29
Гайс, вопрос для разносторонее развитых: читаю стрим с юарта, нада выделять с него фреймы с определенной структурой, если ли чо готовое, или долбаться с ринг буффером? нада у...
Vitaly
9
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
14
Добрый день! Скажите пожалуйста, а какие программы вы бы рекомендовали написать для того, чтобы научиться управлять памятью? Можно написать динамический массив, можно связный ...
Филипп
7
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
длина пакета фиксированная, или меняется?
Okhsunrog
7
Карта сайта