Не так давно кто-то сказал мне, что long
на 64-битных машинах нет 64 бит, и я всегда должен их использовать int
. Это не имело смысла для меня. Я видел, как документы (например, на официальном сайте Apple) говорят, что long
они действительно 64-битные при компиляции для 64-битного процессора. Я посмотрел, что это было на 64-битной Windows и нашел
- Windows:
long
иint
остаются 32-разрядными по длине, а для 64-разрядных целых чисел определены специальные новые типы данных.
(с http://www.intel.com/cd/ids/developer/asmo-na/eng/197664.htm?page=2 )
Что я должен использовать? Должен ли я определить что - то вроде uw
, sw
((ООН) подписали ширину) , как long
если не на Windows, а в противном случае выполнить проверку на bitsize целевого процессора?
sizeof(long) == 8
даже на Windows :-)size_t
или тип итератора для итерации, неint
илиint64_t
size_t
ним становится сложно около отрицательных чисел, потому чтоsize_t
без знака. Такfor(size_t i=0; i<v.size()-2; i++)
не выполняется для вектора размера 0 и 1. Другой пример:for(size_t i=v.size()-1; i>=0; i--)
.size_t
значениями , то результат должен быть сохранен в переменнойptrdiff_t
типа - который разработан , чтобы быть достаточно большим , чтобы провести такой результат и является подписанный тип именно по этой причине!)Ответы:
В мире Unix было несколько возможных вариантов размеров целых чисел и указателей для 64-битных платформ. Двумя наиболее широко используемыми были ILP64 (на самом деле, примеров было очень мало; Cray был одним из них) и LP64 (почти для всего остального). Сокращения происходят от «int, long, указатели 64-битные» и «long, указатели 64-битные».
Система ILP64 была заброшена в пользу LP64 (то есть почти все последующие участники использовали LP64, основываясь на рекомендациях группы Aspen; только системы с длительным наследием 64-битной работы используют другую схему). Все современные 64-битные системы Unix используют LP64. MacOS X и Linux являются современными 64-битными системами.
Microsoft использует другую схему перехода на 64-битную версию: LLP64 («long long, указатели 64-битные»). Это означает, что 32-разрядное программное обеспечение можно перекомпилировать без изменений. Он отличается от того, что делают все остальные, а также требует пересмотра кода для использования 64-битных возможностей. Там всегда был пересмотр необходим; это был просто набор ревизий, отличающийся от тех, которые нужны на платформах Unix.
Если вы разрабатываете свое программное обеспечение на основе имен целочисленных типов, не зависящих от платформы, возможно, используя
<inttypes.h>
заголовок C99 , который, когда типы доступны на платформе, обеспечивает подпись (в списке) и без знака (не в списке; префикс с «u»):int8_t
- 8-битные целые числаint16_t
- 16-битные целые числаint32_t
- 32-разрядные целые числаint64_t
- 64-разрядные целые числаuintptr_t
- целые числа без знака, достаточно большие, чтобы содержать указателиintmax_t
- самый большой размер целого на платформе (может быть больше, чемint64_t
)Затем вы можете кодировать свое приложение, используя эти типы, где это важно, и быть очень осторожными с типами системы (которые могут отличаться). Существует
intptr_t
тип - целочисленный тип со знаком для хранения указателей; Вы должны планировать не использовать его или использовать только как результат вычитания двухuintptr_t
значений (ptrdiff_t
).Но, как указывает вопрос (с недоверием), существуют разные системы для размеров целочисленных типов данных на 64-битных машинах. Привыкнуть к этому; мир не изменится.
источник
short
, что вы называете 16-битным типом? И если вы вызываете 16-битный типchar
для UTF-16 и т. Д., Что вы называете 8-битным типом? Таким образом, использование LP64 оставляет вас с 8-битнымchar
, 16-битнымshort
, 32-битнымint
, 64-битнымlong
, с возможностью расширения вверх до 128-бит,long long
когда (если?) Это становится актуальным. После этого у вас больше степеней 256, чем у вас имен в C (ну, я полагаю, у вас может быть 256-битнаяintmax_t
, и только тогда вы исчерпаете). В этом есть заслуга LP64.Не ясно, если речь идет о компиляторе Microsoft C ++ или Windows API. Однако тега [c ++] нет, поэтому я предполагаю, что он касается API Windows. Некоторые ответы пострадали от гниения ссылок, поэтому я предоставляю еще одну ссылку, которая может гнить.
Для получения информации о типах API Windows, таких как
INT
иLONG
т. Д., Есть страница в MSDN:Типы данных Windows
Информация также доступна в различных заголовочных файлах Windows, таких как
WinDef.h
. Я перечислил несколько соответствующих типов здесь:Столбец «S / U» обозначает подписанный / неподписанный.
источник
Эта статья о MSDN ссылается на ряд псевдонимов типов (доступных в Windows), которые немного более явны в отношении их ширины:
http://msdn.microsoft.com/en-us/library/aa505945.aspx
Например, хотя вы можете использовать ULONGLONG для ссылки на 64-разрядное целое число без знака, вы также можете использовать UINT64. (То же самое касается ULONG и UINT32.) Возможно, это будет немного яснее?
источник
int
а второй 32-битныйlong
, gcc будет предполагать, что указатель на один тип не сможет псевдоним другого, несмотря на их соответствующие представления).Microsoft также определила UINT_PTR и INT_PTR для целых чисел того же размера, что и указатель.
Вот список специфических типов Microsoft - это часть справочника по драйверам, но я считаю, что он действителен и для общего программирования.
источник
Самый простой способ узнать это для вашего компилятора / платформы:
Умножение на 8 состоит в получении битов из байтов.
Когда вам нужен определенный размер, часто проще всего использовать один из предопределенных типов библиотеки. Если это нежелательно, вы можете делать то, что часто происходит с программным обеспечением autoconf, и система конфигурации определяет правильный тип для нужного размера.
источник
Размер в битах
long
на платформах Windows составляет 32 бита (4 байта).Вы можете проверить это, используя
sizeof(long)
.источник
Если вам нужно использовать целые числа определенной длины, вам, вероятно, следует использовать некоторые независимые от платформы заголовки, чтобы помочь вам. Boost - хорошее место для наблюдения.
источник