Каков размер бит в 64-битной Windows?
Не так давно кто-то сказал мне, что 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
((un) signed width) как long
, если нет в Windows, и в противном случае сделать чек на целевом процессоре битрейтом?
Ответы
Ответ 1
В мире Unix было несколько возможных мер для размеров целых чисел и указателей для 64-битных платформ. В основном широко использовались ILP64 (на самом деле это было всего лишь несколько примеров: Cray был одним из них) и LP64 (почти для всего остального). Acronynms исходят из "int, long, pointers are 64-bit" и "long, указатели 64-бит".
Type ILP64 LP64 LLP64
char 8 8 8
short 16 16 16
int 64 32 32
long 64 64 32
long long 64 64 64
pointer 64 64 64
Система ILP64 была оставлена в пользу LP64 (то есть почти все последующие участники использовали LP64, на основе рекомендаций Aspen, только системы с длинным наследием 64-битной операции используют другую схему). Все современные 64-разрядные Unix-системы используют LP64. MacOS X и Linux - это современные 64-разрядные системы.
Microsoft использует другую схему для перехода на 64-разрядную: LLP64 ( "long long, указатели 64-бит" ). Это имеет смысл того, что 32-разрядное программное обеспечение может быть перекомпилировано без изменений. Он имеет недостаток в том, что он отличается от того, что делают все остальные, а также требует пересмотра кода для использования 64-разрядных возможностей. Всегда требовалась ревизия; это был просто другой набор исправлений от тех, которые нужны на платформах Unix.
Если вы создаете свое программное обеспечение вокруг имен целочисленного типа с платформой-нейтралью, возможно, используя заголовок C99 <inttypes.h>
, который, когда типы доступны на платформе, предоставляет в подписанном (указанном) и неподписанном (не в списке) префикс с '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-битных машинах. Привыкните к нему; мир не изменится.
Ответ 2
Неясно, возникает ли вопрос о компиляторе Microsoft С++ или Windows API. Тем не менее, нет тега [С++], поэтому я предполагаю, что это касается Windows API. Некоторые из ответов пострадали от гнили ссылки, поэтому я предоставляю еще одну ссылку, которая может гнить.
Для получения информации о типах API Windows, таких как INT
, LONG
и т.д., в MSDN есть страница:
Типы данных Windows
Информация также доступна в различных заголовочных файлах Windows, таких как WinDef.h
. Я перечислил несколько релевантных типов здесь:
Type | S/U | x86 | x64
----------------------------+-----+--------+-------
BYTE, BOOLEAN | U | 8 bit | 8 bit
----------------------------+-----+--------+-------
SHORT | S | 16 bit | 16 bit
USHORT, WORD | U | 16 bit | 16 bit
----------------------------+-----+--------+-------
INT, LONG | S | 32 bit | 32 bit
UINT, ULONG, DWORD | U | 32 bit | 32 bit
----------------------------+-----+--------+-------
INT_PTR, LONG_PTR, LPARAM | S | 32 bit | 64 bit
UINT_PTR, ULONG_PTR, WPARAM | U | 32 bit | 64 bit
----------------------------+-----+--------+-------
LONGLONG | S | 64 bit | 64 bit
ULONGLONG, QWORD | U | 64 bit | 64 bit
Столбец "S/U" обозначает подпись/без знака.
Ответ 3
В этой статье о MSDN упоминается ряд псевдонимов типов (доступных в Windows), которые немного более явны по отношению к их ширине:
http://msdn.microsoft.com/en-us/library/aa505945.aspx
Например, хотя вы можете использовать ULONGLONG для ссылки на 64-битное целое значение без знака, вы также можете использовать UINT64. (То же самое касается ULONG и UINT32.) Возможно, это будет немного яснее?
Ответ 4
Microsoft также определила UINT_PTR и INT_PTR для целых чисел, которые имеют тот же размер, что и указатель.
Ниже приведен список конкретных типов Microsoft - это часть их ссылки на драйвер, но я считаю, что это справедливо и для общего программирования.
Ответ 5
Самый простой способ узнать его для вашего компилятора/платформы:
#include <iostream>
int main() {
std::cout << sizeof(long)*8 << std::endl;
}
Умножение на 8 - это получение битов из байтов.
Когда вам нужен определенный размер, часто бывает проще использовать один из предопределенных типов библиотеки. Если это нежелательно, вы можете делать то, что часто происходит с программным обеспечением autoconf, и система конфигурации определяет нужный тип для необходимого размера.
Ответ 6
Если вам нужно использовать целые числа определенной длины, вы, вероятно, должны использовать некоторые независимые от платформы заголовки, чтобы помочь вам. Boost - хорошее место для просмотра.