Господа, подскажите, если кто сталкивался. Известно, что при переходе с одной платформы на другую (особенно, если процы разные), мы имеем веселуху с типами данных. Например, int может менять свой размер. Для этого, как правило, люди вводят кучу дефайнов под разные платформы. Например, так поступили создатели NCBI C TK: http://www.ncbi.nlm.nih.gov файлик: ncbistd.h Вырезка: Code (Text): #ifndef Int2 typedef short Nlm_Int2, PNTR Nlm_Int2Ptr; #define Int2 Nlm_Int2 #define Int2Ptr Nlm_Int2Ptr #define INT2_MIN SHRT_MIN #define INT2_MAX SHRT_MAX #endif Я работал с NCBI C TK, но мне он жутко не нравится. Сейчас ковыряюсь как проблему решали создатели APR. Может, кто еще чего подскажет? Что по поводу __u32?
Только int может менять размер, AFAIK. char - всегда 1 байт short int - всегда 2 long int - всегда 4 Кроме размера, к сожалению, иногда меняется ещё и ориентация байтов: big endian vs. little endian. С этим бороться труднее. Чтоб без директив препроцессора обойтись? Не выйдет, IMHO. unsigned long int
В C/C++ меняют размер. 1. указатель/адрес - в зависимости от архитектуры. 2. int - 2/4/8 байт. В старых системах 2, в современных 4, в некоторых современных дурных 8. 3. long int - 4/8 байт. В старых и современных 4, в некоторых новых 8. Про остальные не слышал.
__LITTLE_ENDIAN__ __BIG_ENDIAN__ А разве эти не дефайнятся? Точно. #define UINT32 unsigned long int #ifdef __LITTLE_ENDIAN__ typedef unsigned long int UINT32
вроде такого: Code (Text): unsigned long x = 0xaabbccdd; // sizeof(unsigned long)==4 return *(char *)&x == 0xaa;
Про ориентация можно забыть если не изменяеш тип указателя тк она разная только в памяти. В проциках Hi - всегда старший а Lo - младший тк блоки из которых они состоят одни и теже (принцип построения умножителей, сумматоров и тд) так в AMD64 он должен быть 8, и вообще int должен быть равен разрядности процессора но программеры уже привыкли к 4 хотя в реальном режими он 2 байта (16 разрядный 86). char - всегда 1 байт short - всегда 2 long - всегда 4 long long - всегда 8
SWR Сомнительное утверждение, т.к. в х86-64 размер операнда по умолчанию по прежнему = 32 бита, а 64-битные операнды, если в них нет необходимости - лишь попусту поедают память и увеличивают размер кода
Это только для совместимости (работает в 32 разрядном режиме по дефолту как и P4,P3, и тд в 16 разрядном) но int в си должен быть 8 байт для этой платформы
мдя ребят, проблем действительно есть, нам надо либо тревогу бить, либо переучиваться. вот что мне при сборке GCC на глаза попалось... Code (Text): ... checking if mkdir takes one argument... no checking for char... yes checking size of char... 1 checking for short... yes checking size of short... 2 checking for int... yes checking size of int... 4 checking for long... yes checking size of long... 8 checking for long long... yes checking for long long... (cached) yes checking size of long long... 8 checking whether byte ordering is bigendian... no ... вот с какого х... ээм... перепоя, long = 8 ?!!
SWR Ошибаешься Дефолтный размер операнда - это тот, который не требует префикса переопределения размера, а для использования 64-битных операндов, как известно, по любому небходим префикс REX. Поэтому как ни крути, а в AMD64\EMT64 дефолтный размер 32 бита в любом режиме и злоупотребление 64 битами будет приводить к раздуванию размера кода и данных, увеличению нагрузки на кэши и к снижению производительности. Чтобы не быть голословным придется привести цитаты из мануалов: Intel: AMD: PS: Тут видимо уместно провести аналогию с FPU. Как то один бегинер задавал вопрос почему FPU быстрее работает с dword\qword, а не с tbyte (80 бит) - "родным" типом FPU. С AMD64\EMT64 такая же ситуация, если АЛУ 64-битное, это еще не значит что с "родными" 64 битами процессор будет работать лучше\быстрее, чем со "старыми добрыми" 32
А почему нет то? Изначально же вроде задумывалось int - 4 bytes, long int - 8 bytes, но MicroSoft переделала под себя, отсюда и "с какого перепоя?" ))
Похоже изначально никак не задумывалось. Не помню уже, что говорят на эту тему Керниган и Риччи, но у Страуструпа только: 1 == sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) при этом int - минимум 16 бит, long - минимум 32 бита. (вот насчет этого точно не помню)
Тэкс, господа. Гуд, благодарю. Возник еще один вопрос. wchar_t. У этого типа под Винду все ОК - есть WideCharToMultiByte + MultiByteToWideChar. Под линух есть inconv() (если поддерживается ядром) и iconv (как GNU-библа, если ядро молчит в сторонке) + mbstowcs и wcstombs. Но по поводу последних двух мя терзают смутные сомнения... Итак, цель: спортировать юникодную программу с винды на линух (не вру). Вопрос: может, кто уже шишки себе набил?
Вот что пишут в libc.info.gz: "This sometimes makes a difference as it is expected that the `iconv' functions are used to translate entire texts while the `mbsrtowcs' functions are normally used only to convert single strings and might be used multiple times to convert entire texts." mbstowcs и wcstombs больше похожи на WideCharToMultiByte и MultiByteToWideChar.
Tак AMD64 - гибрид 32 и 64 разрядного процика (для совместимости) как и x86 (16-32) в реальном режиме тоже требует префикс для доступа к 32 разрядом и по дефолту адресует 16 Мож и в AMD64 есть режим когда опкод ненужен будет (я незнаю)
AMD64 Architecture Programmer's Manual Volume 2: System Programming (#24593.pdf) наворотили дай боже, но разобраться можно