November 2019

S M T W T F S
      12
34 5 678 9
10111213141516
17181920212223
24252627282930

Style Credit

Expand Cut Tags

No cut tags
Monday, August 2nd, 2010 11:46 am
struct uniqueEPGKey
{
        int sid, onid, tsid;
...
        bool operator==(const uniqueEPGKey &a) const
        {
                return !memcmp( &sid, &a.sid, sizeof(int)*3);
        }

Молодцы, блин. Сэкономили полстрочки кода.

Upd: “м-мать”, — звонко откликнулось эхо.

unsigned int magic=0;
fread( &magic, sizeof(int), 1, f);
if (magic != 0x98765432)
{
        eDebug("[EPGC] epg file has incorrect byte order.. dont read it");
        fclose(f);
        return;
}

Оригинал этой записи. Комментировать можно тут или там.

Любые материалы из этого блога запрещается использовать на сайте livejournal.ru в любой форме и любом объёме

Monday, August 2nd, 2010 10:52 am (UTC)
Бля.
Monday, August 2nd, 2010 11:10 am (UTC)
Не, оно даже будет работать. Обычно. А когда-нибудь потом сломается..
Monday, August 2nd, 2010 11:12 am (UTC)
Не на x86 каком-нибудь.
Monday, August 2nd, 2010 11:15 am (UTC)
Архитектура тут, скорее всего, ни при чём. У меня сейчас на мипсе работает. Это если когда-нибудь выравнивание случится не по границе int'а. Это редкость, но бывает.
Wednesday, August 4th, 2010 04:49 am (UTC)
А что, оптимизаторы нынче настолько умные, что смотрят так далеко вперёд? Уже давно в потроха сишных не заглядывал, но в [x86 точно] одна из переменных может и в регистре оказаться, например :) Тем более что в memcmp две последних никак не упомянуты.
Monday, August 2nd, 2010 12:00 pm (UTC)
А у инта в c-ях строго фиксированный размер ?
Monday, August 2nd, 2010 12:03 pm (UTC)
Нет. Зависит от архитектуры и иногда от компилятора и его ключей.
Это C++, хотя в данном случае это не принципиально.
Monday, August 2nd, 2010 12:09 pm (UTC)
ну мне кажется если magic проверяется то в зависимости от размера int'а могут быть нюансы :/

Но я с ц имел дело в последний раз в универе, так что могу и ошибаться...
Monday, August 2nd, 2010 12:17 pm (UTC)
В зависимости от размера int нюансов не будет, при его изменении поменяется и sizeof(int). А вот при изменении выравнивания этих int'ов в составе struct может наступить жопа. Если, например, они будут 32-битовыми, а выравниваться будут по границе 64-битовых слов.
Monday, August 2nd, 2010 12:19 pm (UTC)
спасибо, очень толковое объяснение.
Monday, August 2nd, 2010 08:53 pm (UTC)
> Если, например, они будут 32-битовыми, а выравниваться будут по границе 64-битовых слов.
как тогда будет выглядеть массив int-ов? в массиве все элементы расположены друг за другом, на расстоянии, равном размеру элемента. поэтому alignment > size у типов данных не бывает (в gcc атрибутами можно поставить что угодно, но массив из такого типа не получится).

в данном случае компилятор, конечно, имеет право напихать дырок между 3 интами, но я такого не видел и не вижу, зачем это может понадобиться.
Monday, August 2nd, 2010 09:10 pm (UTC)
это не массив, это три отдельных int'а

в массиве все элементы расположены друг за другом, на расстоянии, равном размеру элемента
это из чего следует? Насколько я помню стандарт C, гарантируется только что при инкрементировании указателя на некоторый тип он будет указывать на следующий элемент массива, а на сколько конкретно он увеличится - не регаламентируется. А это вообще C++.

понадобиться может, например, для ускорения работы в 64-битовом режиме процессора с 32-битовыми int'ами. хотя ситуация гипотетическая, ятакого тоже ни разу не видел, но всё равно не понимаю, зачем раскладывать себе потенциальные грабли. Трудно было явно сравнить три int'а что ли?
Monday, August 2nd, 2010 10:12 pm (UTC)
> это из чего следует?
из стандарта. по определению
An array type describes a contiguously allocated nonempty set of objects with a particular member object type, called the element type.
С++ в этом месте совместим с С.
ну и вообще, нету другого выбора -- до С99 единственный способ сделать массив динамической длины это malloc(sizeof(T)*n). в С++ есть new T[n], но malloc тоже поддерживается.

> понадобиться может, например, для ускорения работы в 64-битовом режиме процессора с 32-битовыми int'ами.
не верю. даже если предположить, что у нас нет операции загрузки 32-ух битного слова (если есть, то и говорить не о чем), то добавлять один шифт на 32 для нечетных слов будет дешевле, чем переводить кэш и шину загрузку мусора.

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

в общем, как ни криво написано, в реальной жизни очень маленькая вероятность сломаться.
Tuesday, August 3rd, 2010 06:43 am (UTC)
а для чего тогда вообще придумали выравнивание данных по границе слова, если операции загрузки отдельных байтов всё равно всегда были?
Tuesday, August 3rd, 2010 07:50 pm (UTC)
каких данных? выравнивать 8-битные данные на 64-бита вроде еще не придумывали.

обычно выравнивают по 2 причинам 1) данные размера N удобно грузить, когда они выравнены на N 2) для лучшего расположения в кэше; в частности, если грузить не выровненные данные, load может пересечь границу cache line, что неприятно.

ни 1) ни 2) выравнивание 32-бит на 64 в структуре не требуют.
Tuesday, August 3rd, 2010 06:47 am (UTC)
впрочем, это всё о массивах. а тут три отдельных int'а, хоть и в составе структуры.
Tuesday, August 3rd, 2010 07:52 pm (UTC)
так я и не спорю, что это нарушение стандарта. я говорю, что в реальной жизни не сломается. и это плохо -- уменьшает шансы автора получить по шее.
Monday, August 2nd, 2010 08:49 pm (UTC)
первое выглядит, конечно, плохо, но работать будет всегда.
второе не будет работать, если int не 32 бита.
Monday, August 2nd, 2010 09:04 pm (UTC)
более того, оно зачем-то завязано на endianness, хотя этого легко можно было избежать
Monday, August 2nd, 2010 09:10 pm (UTC)
из следующего поста у меня сложилось ощущение, что файл пишется строго на той же машине, на которой и читается. тогда endianness не очень важна. вообще, если перестать придираться, то, вполне возможно, и int не 32 бита данной программе поддерживать не обязательно (это сейчас только микро-контроллеры всякие).

но как-то неаккуратненько.
Monday, August 2nd, 2010 09:14 pm (UTC)
не совсем. конкретно тот файл /hdd/epg.dat действительно пишется и читается на одной машине, но точно такой же формат используется для импорта EPG из внешних источников, а там он может генерироваться на машине с другой архитектурой, другим размером int'а и другим порядком байт.
Monday, August 2nd, 2010 09:17 pm (UTC)
ну тогда ой
Tuesday, August 10th, 2010 10:19 am (UTC)
А это вообще переносимо? Разве можно надеяться, что все компиляторы расположат sid, onid и tsid в соседних ячейках памяти и именно в этом порядке?
Tuesday, August 10th, 2010 10:32 am (UTC)
порядок внутри структуры - да, иначе бы на си вообще невозможно было писать переносимые программы. вот насчет выравнивания у меня есть сомнения.
Tuesday, August 10th, 2010 11:36 am (UTC)
Со структурой все ясно - int, как я себе представляю, будут выравнены всегда. Не ясно с &sid.