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