Каков размер long в 64-битной Windows? - PullRequest
125 голосов
/ 21 декабря 2008

Не так давно кто-то сказал мне, что 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, и в противном случае выполнить проверку размера целевого битового процессора?

Ответы [ 6 ]

238 голосов
/ 21 декабря 2008

В мире Unix было несколько возможных вариантов размеров целых чисел и указателей для 64-битных платформ. Двумя наиболее широко используемыми были ILP64 (на самом деле, только несколько примеров этого; Cray был одним из таких) и LP64 (почти для всего остального). Сокращения происходят от «int, long, указатели 64-битные» и «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-битных машинах. Привыкнуть к этому; мир не изменится.

47 голосов
/ 19 августа 2012

Не ясно, идет ли речь о компиляторе Microsoft C ++ или Windows API. Однако тега [c ++] нет, поэтому я предполагаю, что он касается API Windows. Некоторые ответы пострадали от гниения ссылок, поэтому я предоставляю еще одну ссылку, которая может гнить.


Для получения информации о типах 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" обозначает подписанный / без знака.

4 голосов
/ 21 декабря 2008

В этой статье на MSDN упоминается ряд псевдонимов типов (доступных в Windows), которые немного более явны в отношении их ширины:

http://msdn.microsoft.com/en-us/library/aa505945.aspx

Например, хотя вы можете использовать ULONGLONG для ссылки на 64-разрядное целое число без знака, вы также можете использовать UINT64. (То же самое касается ULONG и UINT32.) Возможно, это будет немного яснее?

3 голосов
/ 21 декабря 2008

Microsoft также определила UINT_PTR и INT_PTR для целых чисел того же размера, что и указатель.

Вот список определенных типов Microsoft - это часть справочника по драйверам, но я считаю, что он применим и для общего программирования.

2 голосов
/ 21 декабря 2008

Самый простой способ узнать это для вашего компилятора / платформы:

#include <iostream>

int main() {
  std::cout << sizeof(long)*8 << std::endl;
}

Умножение на 8 - получение битов из байтов.

Когда вам нужен определенный размер, часто проще всего использовать один из предопределенных типов библиотеки. Если это нежелательно, вы можете делать то, что часто происходит с программным обеспечением autoconf, и система конфигурации определяет правильный тип для нужного размера.

0 голосов
/ 21 декабря 2008

Если вам нужно использовать целые числа определенной длины, вам, вероятно, следует использовать некоторые независимые от платформы заголовки, чтобы помочь вам. Boost - хорошее место для наблюдения.

...