Процитируем выдержку из статьи Microsoft под названием "The New Data Types" (доступна на Web-сайте компании Microsoft): "Точность этих типов данных отражает изменение точности указателей (то есть, они становятся 32-битовыми в коде Win32 и 64-битовыми в коде Win64). Поэтому приведение указателей к одному из этих типов при выполнении арифметических операций с указателями является безопасным; при 64-битовой точности указателей размер данных этого типа будет составлять 64 бита. Также и типы данных, соответствующие счетчикам, отражают максимальный размер данных, на которые может ссылаться указатель." Таким образом, эти типы данных обеспечивают автоматическое изменение размеров целочисленных типов данных в зависимости от изменения размеров указателей, в связи с чем их иногда называют полиморфными (polymorphic data types) или платформо-масштабируемыми (platform scaled data types) типами данных. Типы данных, соответствующие точности указателей, перечислены в табл. 16.2, взятой из той же статьи.
Наиболее важным из них является тип данных SIZE_T, который уже использовался нами при описании размеров блоков памяти в главе 5.
Наконец, заметьте, что в Win64 размер данных типа HANDLE составляет 64 бита.
Таблица 16.2. Типы данных, соответствующие точности указателей
Тип данных | Описание |
DWORD_PTR | Длинное целое без знака, соответствующее точности указателей. |
HALF_PTR | Половина размера указателя. Используется в структурах, содержащих указатель и два поля небольшого размера. |
INT_PTR | Целое со знаком, соответствующее точности указателей. |
LONG_PTR | Длинное целое со знаком, соответствующее точности указателей. |
SIZE_T | Максимальное количество байтов, на которые может ссылаться указатель. Используется для счетчиков, которые должны охватывать весь диапазон возможных значений указателей. |
SSIZE_T | Тип SIZE_T со знаком. |
UHALF_PTR | Тип HALF_PTR без знака. |
UINT_PTR | Тип INT_PTR без знака. |
ULONG_PTR | Тип LONG_PTR без знака. |
Пример: использование указательных типов данных
Аргументом потока, передаваемым функции потока при вызове CreateThread и _beginthreadex (см. главу 7), является указатель типа PVOID. Иногда программист может захотеть передать функции потока только целочисленное значение, указывающее, например, номер потока или индекс данных в глобальной таблице. Тогда функцию потока, интерпретирующую параметр как целое без знака, можно было бы написать следующим образом:
DWORD WINAPI MyThreadFunc(PVOID Index_PTR) {
DWORD_PTR Index;
…
Index = (DWORD_PTR)Index_PTR;
…
}
Аналогичным образом, зная, что фактический аргумент является целым числом, вы могли бы записать соответствующий участок кода основного потока следующим образом:
…
DWORD_PTR Ix;
…
for (Ix = 0; Ix < NumThreads; Ix++) {
hTh[Ix] = _beginthreadex(NULL, 0, MyThreadFunc, (PVOID)Ix, 0, NULL);
…
}
Заметьте, что в уже существующий код вам придется внести необходимые изменения. Об этом говорится далее в разделе "Перенос существующего кода".
Предостережение
Пока, по крайней мере, в случае первоначальных вариантов реализации, не следует рассчитывать на получение доступа ко всему виртуальному адресному пространству. Размер виртуальных адресных пространств может ограничиваться такими, например, значениями, как 512 Гбайт, что соответствует ограничению данных 39 битами. Можно надеяться, что со временем, по мере эволюции процессоров и систем, указанный верхний предел увеличится.