Уроки разработки 64-битных приложений на языке Си/Си++
Курс состоит из 28 уроков, посвященных знакомству с
Курс состоит из 28 уроков, посвященных знакомству с
Раз уж подняли столь древнюю тему, добавлю свой пример (примерно такой же древности). Пример на несколько обратный эффект — проблема только на
Код — триггер проблемы:
lseek(fd, -sizeof(buf), SEEK_END);
Пытаемся воспроизводить:
#include <stdio.h>
#include <fcntl.h>
int main()
{
printf("%llx\n", (off_t)(-sizeof(int)));
return 0;
}
Выдаёт 0xfffffffc.
Лечение очевидно, неочевидно натыкание на проблему.
off_t
off_t64-битный
#include <stdio.h> #include <unistd.h> int main() { fprintf(stdout, "Size of off_t is %d\n", sizeof(off_t)); }
root@mikenfs:~/{}# gcc -m32 -D_FILE_OFFSET_BITS=32 fileofft.c -o fileofft
root@mikenfs:~/{}# ./fileofft
Size of off_t is 4
root@mikenfs:~/{}# gcc -m32 -D_FILE_OFFSET_BITS=64 fileofft.c -o fileofft
root@mikenfs:~/{}# ./fileofft
Size of off_t is 8
root@mikenfs:~/{}# uname -a
Linux mikenfs 3.13.0-73-generic
Если в 2016 году ещё остались программы, которые считают, что off_t имеет размер 64 или 32 бита, то программеров нужно отправлять на переквалификацию.
off_t под вендой вообще не используется, есть стандартные size_t и ptrdiff_t и никаких проблем.
Вообще справедливости ради нужно отделить мух от котлет, поскольку у нас обсуждение разработки
поскольку у нас обсуждение разработки64-битных приложений
Ну, я с самого начала этой подветки пояснил, что это родственный случай (на ту же проблему переходов между 32- и
Если это FAT, то в любом случае размер файла не выходит за рамки32-битного числа, независимо от x86 или x64 платформы.
Такой подход некорректен тем, что привязывает свойства интерфейса к конкретной FS, чего не делала даже Windows (имея в запасе, например, монтирование чего угодно с Novell или Unix по SMB, NFS и многим другим).
Описанные интерфейсы Windows и Unix никак не привязаны к конкретной FS (хотя указанная SetFilePointer, в отличие от SetFilePointerEx, оптимизирована на упрощение работы, когда смещение передаётся только как 32 бита).
(И ещё Вы почему-то тут не включаете exFAT в FAT. Мне такое деление непонятно — или называть каждый вариант FAT отдельно, или exFAT ничем тут не выделяется, кроме лицензирования.)
Твоё высказывание слишком туманно — с каким именно вариантом программиста надо отправлять на переквалификацию? Три варианта прочтения:
1) он думает, что всегда 32 бита
2) он думает, что всегда 64 бита
3) он думает, что 32 или 64 бита, в зависимости от чего-то
Если первое — согласен на 147%.
Если второе — я бы с удовольствием был таким программистом (тем более что я в начале этой части карьеры плотно сел на FreeBSD, которая сделала off_t
$ gcc -o fileofft fileofft.c -m32
$ ./fileofft
Size of off_t is 4
и тут, видимо, надо включить каким-то образом одну из названных тобой опций, чтобы оно стало цивилизованным. Хотя _LARGEFILE64_SOURCE тут не помогло. И неудивительно — почитал про него — оно добавляет off64_t и функции для него типа fseeko64, а не меняет off_t.
Если третий вариант — то вообще непонятно, к чему такое высказывание.
Если хочешь, чтобы я тебя понял — уточни, что имелось в виду.
И неудивительно — почитал про него — оно добавляет off64_t и функции для него типа fseeko64, а не меняет off_t.Оно добавляет альтернативный 64 битовый интерфейс open64()/lseek64()/etc. Если в 32битовой системе нужна поддержка больших файлов, то объявляем _LARGEFILE64_SOURCE и используем его.
_FILE_OFFSET_BITS=64Это делает прозрачным использование open()/lseek(). Хотя на самом деле вызываются аналоги open64()/lseek64(). Соответственно off_t равен off64_t. Попытка вдохнуть поддержку больших файлов в старый код, которая часто оборачивается проблемами подобными, что ты описал в начале треда.
Т.к. это POSIX расширения, то в ОС обе могут быть заранее предефайнены, поэтому в препроцессоре нужно анализировать их значения, либо при компиляции явно задавать. Это всё.
тем более что я в начале этой части карьеры плотно сел на FreeBSD, которая сделала off_tQNX первая сделала time_t unsigned, проблемы выстреливают до сих пор, пару лет назад я даже правил git, ибо он плотно был уверен, что time_t signed. И такого валом.64-битным ещё в 2.0, и не представлял себе, что бывает иначе, пока не столкнулся с некоторыми странными системами вроде старой солярки
Оно добавляет альтернативный 64 битовый интерфейс open64()/lseek64()/etc.
Спасибо, кэп :) Со вчера я это уже знаю (точнее, вспомнил заново, потому что давно не требовалось, и прочно забыл).
И такого валом.
Я надеюсь, ты не хочешь этим сказать, что фряшники неправы и что на самом деле их моральным долгом было заставить юзеров иметь ещё лет на 20 вперёд активный церебральный секс с разрядностью off_t и сопутствующих функций 8-\
Я надеюсь, ты не хочешь этим сказать, что фряшники неправы и что на самом деле их моральным долгом было заставить юзеров иметь ещё лет на 20 вперёд активный церебральный секс с разрядностью off_t и сопутствующих функций 8-\Я хочу сказать, что без сопутствующих знаний — это бесполезно. Пример — я когда-то учавствовал в разработке Fido софта, писали тоссер и строили индексы. off_t торчала в структуре, которая сгружалась на диск, получили несовместимые между платформами файлы. Второй случай, чувак сделал всё правильно, но неправильно определил тип и выставил внаружу для записи на диск uint32_t offset, и вся поддержка 64 битных смещений коту под хвост.
#if (sizeof(off_t)==8) uint64_t offset; #elif (sizeof(off_t)==4) # if defined(__LITTLEENDIAN__) uint32_t offset; uint32_t offset_hi; #elif defined (__BIGENDIAN__) uint32_t offset_hi; uint32_t offset; #else #error blah2 #endif #else #error blah #endif
Как часто ты видешь в коде подобное? Вот и я о том же.
P.S. Пример с макросами не очень удачен — это для message passing между виртуальными машинами с разной разрядностью.
нужно отправлять на переквалификацию.А как быть с вашей работой под рутом, в 2016ом году?
А как быть с вашей работой под рутом, в 2016ом году?Мне можно, я взрослый.
Коллеги, «Си» ещё где нибуть используется кроме embedded ? (в смысле работы по Украине), по вакансиям очень глухо, даже разработка ядра никому не нужна сейчас ?
Спасибо за ответ, но там как мне известно С++, а не Си, да и то под игры для мобильника часто используют Unity/C#, а «плюсы» всё же реже, хотя может вам виднее.
PS: Из-за опыта на Си мне как-то не лезит вся эта ООП-xрень вот и ищу где может Си ещё пригодится ...
Морда для JNI и вообще native API андроида — на С. Если вы посмотрите на интерфейс С библиотек (ну curl, например), то увидите кучу функций, где первым параметром идёт хэндл (curl.haxx.se/...
А частота использования лично для вас имеет очень малое значение. Вам важно, сколько платят и как легко устроиться, а это может не коррелировать с частотой.
ООП — это самая меньшая хрень, с которыми столкнётесь в проектах. Плюсы актуальны для 3D-графики, и везде где сложный рендеринг. Для разработки крупных приложений под современную винду всё равно придётся юзать дот нет, часть кода будет на C#, часть под управляемый C++, ну и часть на неуправляемом C++. Кроме того, основная часть логики скорее всего будет выноситься в скрипты. Можно конечно писать только на C# под Unity. Можно вообще на JS под WebGL.
Плюсы актуальны для 3D-графики, и везде где сложный рендеринг.— Этож там математики туева-куча, плюс специфика С++ это вообще застрелится можно с такой работой ...
3D увязана с основами аналитической геометрии, матричное исчисление, кватернионы. Ну ещё немного кода выносится в шейдеры, вот там почти чистый C, без ООП :)
Ну вообще-то C99 оговаривает наличие типов intN_t, uintN_t и оговаривает их точный размер. Если нужны типы с количеством бит «не менее чем», то uint_leastN_t и int_leastN_t. А при использовании DWORD, u_int16_t, u_int8_t внутри вашего кода, а не для передачи параметров в системные функции, то кто ж вам всем доктор:)
те же — (int, long, short, etc) то разница действительно минимальная, но если везде по коду юзаются всякие (u_int16_t, u_int8_t, DWORD etc) то разница между системами становится значительней, хотя, по идее эти системные типы как раз и не должны меняться в размерности, при переходе на 64 бит.
Авторы курса разрабатывают платную софтину для MS VS 2010, поэтому виндовая направленность не должна вызывать удивление: -)
Это точно, про VS2015 походу не знают. Про IA-64 упоминают, про ARM упоминаний там нет. Про модификатор __vectorcall и связанную тему — тоже не написали.
про VS2015 походу не знают
Да, машины времени им точно недостаёт.
Плохо, что, в основном, статья описывает 64 битное программирование под виндой, программирование под 64 битными версиями линуха упоминается вскользь.
30 коментарів
Додати коментар Підписатись на коментаріВідписатись від коментарів