Каков размер бит в 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 - хорошее место для просмотра.