- 1
- 2
Comparing structs with, let's say, memcmp, does not work,
as you end up comparing the "unspecified" padding bytes as well — you must compare member-by-member.
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
+2
Comparing structs with, let's say, memcmp, does not work,
as you end up comparing the "unspecified" padding bytes as well — you must compare member-by-member.
While writing this post, the author observed that some verions of GCC (experimentally, >= 4.7, < 8.0) do not zero padding if an empty intializer list is passed, under certain a certain code pattern; if an entire struct (i.e. sizeof(STRUCTNAME)) is subsequently memcpy'd after assigment of its members, and this intermediate buffer is what is used by the code going forward. This appears to be based on how optimization passes interact with GCC's built-in memcpy, since passing -fno-builtin-memcpy returns the behavior to the expected.
https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2019/october/padding-the-struct-how-a-compiler-optimization-can-disclose-stack-memory/
3.14159265 18.11.2019 13:52 # 0
guest8 18.11.2019 13:55 # −999
XYPO3BO3 18.11.2019 18:47 # 0
j123123 18.11.2019 19:46 # 0
И инициализировать через этот говномассив нулями. Тогда там все эти говнопаддинги занулиться должны
bormand 18.11.2019 19:48 # +1
А должны ли?)
guest8 18.11.2019 19:59 # −999
j123123 18.11.2019 20:06 # 0
На всякий случай, в GCC предусмотрена особая хуйня __attribute__ ((may_alias))
Видишь как всё просто
3.14159265 18.11.2019 19:50 # +1
Проблема в том что когда мы начнём писать в поля значения, компилеру ничего не помешает опять засрать паддинги ворециями.
Допустим мы пишем uint8_t а и uint8_t с. А компилер джва присваивания оптимизирует в один mov с мусором в паддинге.
Ниже по треду bormand уже пояснял.
bormand 18.11.2019 19:51 # +1
j123123 18.11.2019 20:09 # +2
Не, ну ясен хер что это говно и костыли, в крестах кстати type punning через union это вообще UB.
3.14159265 18.11.2019 20:15 # +2
>каст структуры в структуру
>>цари
>>структуры
Это несовместимые понятия.
Повторюсь:
Цари используют массивы, единственно полезную структуру данных.
В массивах паддинга нет by design.
guest8 18.11.2019 20:17 # −999
guest8 18.11.2019 20:18 # −999
guest8 18.11.2019 20:27 # −999
guest8 18.11.2019 20:30 # −999
guest8 18.11.2019 20:37 # −999
guest8 18.11.2019 20:39 # −999
guest8 18.11.2019 20:41 # −999
guest8 18.11.2019 20:43 # −999
guest8 18.11.2019 23:48 # −999
guest8 19.11.2019 00:01 # −999
guest8 19.11.2019 00:24 # −999
guest8 19.11.2019 00:26 # −999
guest8 19.11.2019 00:31 # −999
guest8 19.11.2019 01:08 # −999
XYPO3BO3 18.11.2019 20:57 # +1
Т. е. если у нас struct {int coq; char rooster; double xuroz;} petuh[100500]; то это можно заменить на int petuh_coq[100500]; char petuh_rooster[100500]; double petuh_xuroz[100500];
При итерации по таким массивам не будет ни дурацких паддингов, ни хромого шага.
guest8 18.11.2019 20:59 # −999
XYPO3BO3 18.11.2019 21:05 # +1
Хотя возможно, я фигню написал, и это не имеет значения. Нужно смотреть конкретную задачу, чтобы понять, что и в каком порядке нам придётся доставать из массива.
guest8 18.11.2019 22:03 # −999
j123123 18.11.2019 21:16 # 0
Только вот может быть всякая хуйня с кешмиссами
XYPO3BO3 18.11.2019 21:22 # +1
XYPO3BO3 18.11.2019 21:16 # 0
XYPO3BO3 18.11.2019 21:18 # +1
http://govnokod.ru/5286#comment69576
j123123 18.11.2019 21:19 # +1
XYPO3BO3 18.11.2019 21:21 # +1
j123123 18.11.2019 21:29 # +2
j123123 18.11.2019 20:13 # 0
И тогда проблем нет. Осталось изобрести метушню на крестоговне, которая эти паддинги нагенерирует.
j123123 18.11.2019 21:41 # 0
guest8 18.11.2019 21:45 # −999
j123123 18.11.2019 21:48 # 0
guest8 18.11.2019 21:54 # −999
XYPO3BO3 19.11.2019 10:45 # 0
gost 18.11.2019 23:37 # 0
j123123 19.11.2019 23:19 # 0
guest8 19.11.2019 23:32 # −999
gost 19.11.2019 23:35 # 0
guest8 18.11.2019 14:18 # −999
XYPO3BO3 18.11.2019 14:20 # +2
guest8 18.11.2019 14:23 # −999
XYPO3BO3 18.11.2019 14:25 # 0
3.14159265 18.11.2019 16:42 # 0
Цари используют массивы, единственно полезную структуру данных.
bormand 18.11.2019 16:45 # 0
j123123 20.11.2019 07:01 # 0
Что там кстати стандарт говорит насчет выравниваний для базовых типов? Может ли быть ситуация, что int у нас 5-байтный, но требование к выравниванию у него 2 байт, и тогда с массивом получится хуита вида
?
Тогда и без структур будут паддинги
bormand 20.11.2019 11:25 # 0
Дык там паддинги будут в самих структурах, а не между элементами массива...
> int 5-байтный
Х.з., конкретной формулировки не нашёл. Но там написано, что int'ы могут содержать padding биты. Т.е. скорее всего твоё выравнивание на 2 байта будет встроено внутрь самого int'а. Но это не точно.
XYPO3BO3 20.11.2019 12:02 # 0
j123123 20.11.2019 19:45 # 0
guest8 20.11.2019 19:48 # −999
j123123 20.11.2019 19:55 # 0
Типа
char* pituh = malloc(100); double cock; memcpy(&cock, pituh + 1, sizeof(cock));
j123123 25.11.2019 17:10 # 0
Интересно, такая хуйня где-нибудь используется?
XYPO3BO3 26.11.2019 01:00 # +1
guestinxo 26.11.2019 01:05 # +1
guest8 26.11.2019 01:10 # −999
j123123 26.11.2019 11:14 # +2
А где я такое заявлял? Мантисса отдельно, экспонента отдельно, знаковый битик отдельно. http://www.softelectro.ru/ieee754.html
Поэтому кстати в плавучих 754-х питухах есть отрицательный и положительный ноль, в отличии от знаковых целочисленных питухов в дополнительном коде(two’s complement), где такой хуйни нет.
А вот беззнаковых плавучих 754-х питухов не завезли к сожалению, поэтому на каждого такого питуха будет тратиться целый лишний бит
XYPO3BO3 26.11.2019 11:36 # +2
1/32 = 3,125%
1/64 = 1,5625%
1/80 = 1,25%
Так себе экономия. Зато потеря пирфоманса от упаковки/распаковки. Разве что для архивного формата пойдёт.
У меня другое предложение: добавить этот бит к мантиссе либо к порядку, чтобы расширить точность или диапазон. У целых чисел этот бит как раз расширяет верхнюю границу. Да, получится плавающий питух, не полностью совместимый с IEEE 754.
nyTuH_nugop 20.11.2019 21:39 # 0
Это же отрыжка 8087, на нормальных платформах старым говном не пользуются, там есть нативная поддержка banaly64
gost 20.11.2019 11:46 # +2
Выравнивание должно быть степенью двойки:
(§6.11/4)
У char'ов оно должно быть самым маленьким:
(§6.11/5,6)
А вот про выравнивание остальных фундаментальных типов я не нашёл ничего, кроме намёка на то, что оно есть:
(§6.9.1/3)
guest8 18.11.2019 14:28 # −999
guest8 18.11.2019 14:30 # −999
bormand 18.11.2019 14:46 # +1
XYPO3BO3 18.11.2019 15:14 # 0
bormand 18.11.2019 15:23 # 0
3.14159265 18.11.2019 16:47 # 0
Превращает простейшие вещи в унылое оопешное шарпожабство с необходимостью писать ручные equalsы на каждое поле, сеттеры и копирующие конструкторы.
bormand 18.11.2019 17:01 # 0
guest8 18.11.2019 17:03 # −999
3.14159265 18.11.2019 17:17 # 0
XYPO3BO3 18.11.2019 17:22 # 0
3.14159265 18.11.2019 17:25 # 0
Выберёт из джвух вариантов:
1) NaN == NaN //always false
2) UB
XYPO3BO3 18.11.2019 17:28 # 0
3.14159265 18.11.2019 17:33 # +2
Ручками писать сравнения каждого поля.
А флоаты никто не сравнивает через ==. Это делают через эпсилон, как учили в школе.
C опциональной обработкой NaNа согласно логике кода.
Тарас же для игр использовал сугубо флоаты, потому прекрасно понимал что memcmp это кулцхакирство.
guest8 18.11.2019 18:04 # −999
guest8 18.11.2019 18:04 # −999
bormand 18.11.2019 18:09 # 0
guest8 18.11.2019 18:22 # −999
bormand 18.11.2019 19:34 # 0
XYPO3BO3 18.11.2019 18:33 # 0
3.14159265 18.11.2019 19:36 # 0
Это кроссязыковое свойство между прочим.
Браузер от такого сравнения тоже почему-то не падает.
guest8 18.11.2019 19:40 # −999
XYPO3BO3 18.11.2019 19:50 # 0
Никак не могу запомнить, зачем этот знак нужен в «Ruby».
guest8 18.11.2019 19:52 # −999
XYPO3BO3 18.11.2019 19:41 # 0
nyTuH_nugop 18.11.2019 20:34 # 0
3.14159265 18.11.2019 19:43 # +2
Все операции сравнения с NaN возвращают false.
Кроме !=
Это записано не в сишном стандарте, а стандарте для флоатов: IEEE 754.
Потому оно по идее должно быть однородно во всех языках.
j123123 18.11.2019 22:09 # +1
guest8 18.11.2019 22:24 # −999
guest8 18.11.2019 22:27 # −999
XYPO3BO3 20.11.2019 11:28 # 0
А в остальных языках сравнивать плавающих питухов на точное равенство нельзя. Даже в «PHP».
3.14159265 18.11.2019 19:54 # 0
«Патамучто это плавающий питух, который априори говно. И чем вы быстрее это поймёте, чем будет лучше.» ⓒ
http://govnokod.ru/13189#comment182595
XYPO3BO3 18.11.2019 22:28 # 0
Тем не менее, у типа real были значения -0 и +0, а сравнивать на равенство тоже приходилось через эпсилон.
guest8 18.11.2019 22:29 # −999
XYPO3BO3 18.11.2019 22:33 # 0
Шутку не знаю.
guest8 18.11.2019 22:34 # −999
guest8 18.11.2019 22:37 # −999
guest8 18.11.2019 22:38 # −999
XYPO3BO3 18.11.2019 22:41 # +1
guest8 18.11.2019 22:42 # −999
guest8 18.11.2019 22:47 # −999
guest8 18.11.2019 22:49 # −999
XYPO3BO3 18.11.2019 22:56 # 0
Если не указать знак типа, то может создаться целочисленная переменная (ну типа как в старой сишке, если не указать тип, то будет int).
guest8 18.11.2019 22:58 # −999
3.14159265 18.11.2019 23:22 # 0
Не. Этот новодел уже в QB завезли.
В олдбейсике, том что с метками, такое не работало. Только значок доллара для строк.
XYPO3BO3 18.11.2019 23:27 # 0
3.14159265 18.11.2019 23:38 # 0
MID$, LEFT$
А других суффиксов я не припоминаю.
Я кажется экспериментировал с другими значками (документации ведь не было), вроде они все падали с ошибкой.
Может какой-то другой, более поздний диалект. Но кроме QB я больше такого нигде не видел.
3.14159265 18.11.2019 23:11 # 0
>был же такой?
Был. И не у одного тебя.
Steve_Brown 19.11.2019 10:36 # 0
CEMEH 19.11.2019 16:12 # 0
CEMEH 19.11.2019 16:18 # 0
bormand 19.11.2019 16:22 # 0
3.14159265 18.11.2019 23:18 # 0
Бейсик (ещё до мелкомягких) во многом вырос именно из фортрана.
Строки-метки, операторы типа IF X THEN a где a — номер метки; динамическая типизация, пресловутый god is real.
Причём, если в фортране были целые, то в бейсике не стали заморачиваться, и сделали всё даблами. Впоследствии js заимствовал эту парадигму.
ANDы и ORы по каким-то хитрым, неявным правилам конвертились в целые. Прям как в яваскрипте.
We made no distinction between floating-point arithmetic; we used only double precision floating-point internally, and adopted several strategies to make loop termination come out right.
3.14159265 18.11.2019 23:34 # 0
DIMENSION ARR(3,4)
DIM ARR(3,4)
XYPO3BO3 19.11.2019 18:01 # 0
Реализацию чисел в разных бейсиках не изучал. Помню только, что операции целочисленного деления и вещественного явно различались (для целочисленного использовался обратный слэш).
В «Кубейсике», как я уже заметил, целые и вещественные различались явно. Для переменных использовались разные суффиксы (%, !, &, #) либо директивы DEFINT/DEFSNG/DEFLNG/DEFDBL (для любителей венгерки) либо спецификаторы в выражении DIM (DIM AS INTEGER, DIM AS SINGLE, DIM AS LONG, DIM AS DOUBLE).
Целые и вещественные были ещё где-то разделены, помимо «Кубейсика». Я уже отметил суффиксы % и !, но точно не вспомню, в каких реализациях они поддерживались. Придётся перебирать.
В реализациях, которыми я пользовался, AND и OR можно было использовать только в выражении IF. То есть булев тип ни во что не кастовался и даже сохранить его в переменной было нельзя. Вот так булев тип был ущемлён в правах.
XYPO3BO3 19.11.2019 18:24 # 0
Applesoft BASIC: был суффикс % для целого питуха; булев тип кастовался в целые.
http://wiki.apple2.org/index.php?title=Applesoft_BASIC_Ref#Nume ric_Expressions_and_Assignments:
GW-BASIC: четыре типа числовых переменных, как в «Кубасике».
https://hwiegman.home.xs4all.nl/gw-man/index.html
BBC BASIC: есть суффикс % для целого питуха.
http://www.bbcbasic.co.uk/wiki/doku.php?id=number_20conversion_20in_20b asic
Вильнюсский Бейсик (БК-0010): три типа числовых переменных (суффикс % для целых и суффиксы ! и # для двух типов плавающих питухов).
http://www.emuverse.ru/wiki/УКНЦ_Бейсик_Описание_языка
Вот Sinclair Basic целых и плавающих питухов не различал.
guest8 19.11.2019 18:30 # −999
CEMEH 19.11.2019 18:35 # 0
XYPO3BO3 19.11.2019 18:41 # 0
Это и есть «Quick Basic», который я упоминал раньше.
>> бейсики для spectrum
Это «Sinclair BASIC».
Остальные нужно проверить, да.
XYPO3BO3 19.11.2019 19:21 # 0
https://www.atariarchives.org/basic/showpage.php?page=53
«Commodore BASIC»: был суффикс % для целых, в противном случае питух считался плавающим. Булев тип кастовался в целый.
http://www.zimmers.net/cbmpics/cbm/c65/c65manual.txt
В «UBASIC» был суффикс % для «маленьких» чисел (они назывались short variables; занимали одно машинное слово) и # для «больших» чисел (они назывались extra variables; могли вместить до 540 машинных слов). Причём одна и та же переменная могла хранить целое число, рациональное, вещественное, комплексное или многочлен. Да, различались рациональные и вещественные, а так же в переменной можно было хранить многочлен одной переменной (лямбды в Бейсике, ужас).
ftp://ftp.bu.edu/mirrors/simtelnet/msdos/ubasic/
В документации по «Amiga BASIC» нашёл суффиксы %, !, # на 197-й странице:
https://archive.org/download/AmigaBasic
«Power BASIC» был сильно перегружен. Для числовых переменных была куча суффиксов:
Byte (?)
Word (??)
Integers (%)
Double-word (???)
Long integers (&)
Quad integers (&&)
Single-precision floating-point (!)
Double-precision floating-point (#)
Extended-precision floating-point (##)
Currency (@)
Extended-currency (@@)
3.14159265 20.11.2019 17:35 # 0
Не сильнее чем современные кресты и хаскели.
guest8 20.11.2019 17:52 # −999
guest8 20.11.2019 19:42 # −999
3.14159265 20.11.2019 17:38 # 0
XYPO3BO3 20.11.2019 17:55 # 0
А если она после имени переменной, то в некоторых реализациях она означает большого плавающего питуха (double или типа того).
guest8 19.11.2019 18:35 # −999
CEMEH 19.11.2019 18:48 # 0
guest8 19.11.2019 18:52 # −999
guest8 19.11.2019 19:10 # −999
XYPO3BO3 19.11.2019 19:21 # 0
guest8 19.11.2019 19:25 # −999
XYPO3BO3 19.11.2019 19:28 # 0
CEMEH 19.11.2019 19:42 # 0
guest8 18.11.2019 22:32 # −999
guest8 18.11.2019 22:34 # −999
nyTuH_nugop 18.11.2019 22:41 # 0
XYPO3BO3 18.11.2019 22:34 # 0
У «Бейсика» тоже были свои типы плавающих питухов. Гугли MBF (Microsoft binary format).
guest8 18.11.2019 22:35 # −999
XYPO3BO3 18.11.2019 22:39 # 0
Операции с типами IEEE754 переключались на хардварные, если процессор их поддерживал (модуль SYSTEM проверял это при старте программы), а вот операции с типом real всегда оставались софтварными, потому что ни один проц такой царский тип не поддерживал.
MAKAKA 18.11.2019 22:40 # 0
макака думала, что real это у них был double
Кстати, о разницах между реализациями питуха
Знаешь такой бугор
https://en.wikipedia.org/wiki/Strictfp
?
XYPO3BO3 18.11.2019 22:51 # 0
Про strictfp что-то слышал, но пока не копал этот вопрос.
guest8 20.11.2019 18:17 # −999
XYPO3BO3 18.11.2019 17:17 # 0
guest8 18.11.2019 17:34 # −999
3.14159265 18.11.2019 17:38 # +2
Во-1. Для 100500 полей есть массивы. Нет, я серьёзно.
Во-2. В жабамире уже давно никто ничего вручную не сравнивает, @lombok.EqualsAndHashCode
https://projectlombok.org/features/EqualsAndHashCode
guest8 18.11.2019 17:41 # −999
3.14159265 18.11.2019 17:49 # 0
Там два десятка правил, как правильно сравнивать. И парочка исключений из этих правил.
Список pitfalls по твоей ссылке достойный, но там есть ещё парочка: типа невозможности найти объект с мутабельными полями в хеш-мапе, плюс те же флоаты.
Блох вопросу equals посвятил треть своей книжки.
Потому никто их руками обычно не пишет, а либо генерируют через IDE, либо @lombok.EqualsAndHashCode.
guest8 18.11.2019 17:51 # −999
guest8 18.11.2019 17:54 # −999
3.14159265 18.11.2019 18:04 # +2
Если данные разнородные, то просто будет паддинг до интов.
В сишке есть дико идиоматичная инициализация массивов, подобная структурам.
И в сишке есть енумы c опциональной автонумерацией.
Адресация идёт строго через енум, никаких магических цифр.
Ну и соответственно никто не мешает делать memcpy, memcmp и прочие царизмы.
guest8 18.11.2019 18:37 # −999
guest8 18.11.2019 18:39 # −999
3.14159265 18.11.2019 19:45 # 0
Ага. Вот это просто суперидиоматичная фича сишки.
http://govnokod.ru/24276
CEMEH 19.11.2019 18:41 # 0
guest8 19.11.2019 18:47 # −999
CEMEH 19.11.2019 19:06 # 0
3.14159265 18.11.2019 16:41 # +2
А у массивов паддинга нет by design.
bormand 18.11.2019 14:20 # 0
guest8 18.11.2019 14:27 # −999
bormand 18.11.2019 14:49 # 0
XYPO3BO3 18.11.2019 14:30 # 0
3.14159265 18.11.2019 16:39 # +1
https://godbolt.org/z/dPHBkb
Мусор зануляется.
Добавь -fno-builtin-memcpy и тогда из паддингов пропадёт мусор: 7F 05 05
3.14159265 18.11.2019 17:11 # +3
http://govnokod.ru/9686#comment132740
gost 18.11.2019 18:37 # +2
https://gcode.space/ngk/#!/search?user=TheCalligrapher
guest8 18.11.2019 18:51 # −999
guest8 18.11.2019 18:52 # −999
gost 18.11.2019 18:54 # 0
guest8 18.11.2019 18:57 # −999
guest8 18.11.2019 19:00 # −999
gost 18.11.2019 19:02 # 0
TOPT 18.11.2019 19:06 # +4
XYPO3BO3 19.11.2019 00:16 # 0
guest8 20.11.2019 18:17 # −999
bormand 20.11.2019 19:14 # 0