Каков размер long в 64-битной Windows?

Не так давно кто-то сказал мне, что long не 64 бит на 64 битных машинах и я всегда должен использовать int, Это не имело смысла для меня. Я видел, как документы (например, на официальном сайте Apple) говорят, что long действительно 64 бит при компиляции для 64-битного процессора. Я посмотрел, что это было на 64-битной Windows и нашел

  • Окна: long а также int остаются 32-разрядными, и для 64-разрядных целых чисел определены специальные новые типы данных.

http://www.intel.com/cd/ids/developer/asmo-na/eng/197664.htm?page=2)

Что я должен использовать? Должен ли я определить что-то вроде uw, sw ((не) ширина со знаком) как long если не на Windows, а в противном случае сделать проверку на размер процессора целевого процессора?

8 ответов

В мире 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-битных машинах. Привыкнуть к этому; мир не изменится.

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


Для получения информации о типах Windows API, таких как INT, LONG и т.д. есть страница на MSDN:

Типы данных Windows

Информация также доступна в различных заголовочных файлах Windows, таких как WinDef.h, Я перечислил несколько соответствующих типов здесь:

Тип | S/U | х86    | x64
----------------------------+-----+--------+-------
БАЙТ, БУЛЬЯНСКИЙ | U   | 8 бит | 8 бит
---------------------------- + ----- + -------- + ------ -
КОРОТКИЙ | S | 16 бит | 16 бит
USHORT, WORD                | U   | 16 бит | 16 бит
----------------------------+-----+--------+-------
INT, LONG                   | S   | 32 бит | 32 бит
UINT, ULONG, DWORD          | U   | 32 бит | 32 бит
----------------------------+-----+--------+-------
INT_PTR, LONG_PTR, LPARAM   | S   | 32 бит | 64 бит
UINT_PTR, ULONG_PTR, WPARAM | U   | 32 бит | 64 бит
---------------------------- + ----- + -------- + ------ -
ДЛИННЫЕ | S   | 64 бит | 64 бит
УЛОНГЛОНГ, QWORD            | U   | 64 бит | 64 бит

Столбец "S/U" обозначает подписанный / неподписанный.

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

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

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

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

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

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

#include <iostream>

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

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

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

Для истории того, как был сделан выбор для UNIX и Windows (разные варианты были вероятными, Microsoft не была глупой, учитывая ее кодовую базу): Долгая дорога к 64-битам - Double Double, Toil and Trouble, в https://queue.acm.org/detail.cfm?id=1165766 Очередь за 2006 г. или https://dl.acm.org/doi/pdf/10.1145/1435417.1435431 CACM за 2009 г.

Примечание. Я участвовал в разработке 64/32-разрядного MIPS R4000, внес предложение, которое привело к созданию <inttypes.h>, и написал раздел C99, объясняющий мотивы использования long long.

Размер в битах long на платформах Windows - 32 бита (4 байта).

Вы можете проверить это, используя sizeof(long).

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

Другие вопросы по тегам