Вход/Регистрация
Системное программирование в среде Windows
вернуться

Харт Джонсон М.

Шрифт:

137 pIn = (TCHAR _based(pInFile)*)*(LPDWORD)pX;

138

139 while ((*pIn != CR || *(pIn + 1) != LF) && (DWORD)pIn < FsIn) {

140 WriteFile(hStdOut, pIn, TSIZE, &nWrite, NULL);

141 pIn++;

142 }

143 pX += RSize;

144 }
 

Сообщения компилятора далее приводятся, но прежде чем ознакомиться с ними, вы, возможно, захотите просмотреть код, чтобы определить возможные причины выдачи будущих предупреждающих сообщений. Не забывайте о том, что нашей целью является придание программе такого вида, который обеспечивает ее сборку и корректное выполнение как в режиме Win32, так и в режиме Win64.

Предупреждающие сообщения компилятора

Предупреждающие сообщения компилятора для этого фрагмента кода отчетливо демонстрируют неявное предположение о том, что размер указателя составляет 4 байта.

SORTMM.C(137) : warning C4312: 'type cast' : conversion from 'DWORD' to 'TCHAR __based(pInFile) *' of greater size

SORTMM.C(139) : warning C4311: 'type cast' : pointer truncation from 'TCHAR __based(pInFile) *' to 'DWORD'

Первое предупреждение (строка 137) является существенным. Разыменование рХ после его приведения (type cast) к типу LPDWORD приводит к 32-битовому значению, которое затем назначается указателю pIn. Почти с полной уверенностью можно утверждать, что разыменование pIn вызовет исключение или приведет к возникновению иной серьезной ошибки. Правильным решением для строки 137 будет замена приведения к типу LPDWORD приведением к типу указателя LPTSTR следующим образом:

pIn = (TCHAR _based(pInFile)*)*(DWORD_PTR)pX;

Сообщение для строки 139 довольно интересно, поскольку мы сравниваем базовый указатель с размером файла. Если предположить, что файл не является гигантским, то на это предупреждение можно не обращать внимания. При этих условиях можно было бы проигнорировать и сообщение для строки 137. Однако мы учтем перспективу и приготовимся к работе с гигантскими файлами, пусть даже типом FsSize пока и является DWORD. Допуская полный диапазон значений указателя, мы должны преобразовать строку 139 следующим образом:

while ((*pIn != CR || *(pIn + 1) != LF) && (SIZE_T)pIn < (SIZE_T)FsIn) {

Второй сегмент, относящийся к шагу 2b, порождает дополнительные предупреждающие сообщения, связанным с усечением типов (pointer truncation). Соответствующий фрагмент кода представлен в программе 16.2.

Программа 16.2. sortMM: код до подготовки к переносу в Win64, часть 2

…

40 DWORD, KStart, KSize;

174 /* Шаг 2b: Получить первый ключ; определить размер и начальный адрес ключа. */

175

176 KStart = (DWORD) pInScan;

177 /* Вычисляем адрес начала поля ключа. */

178 while (*pInScan !=''&& *pInScan != '\t') pInScan++;

179 /* Вычисленный конец поля ключа. */

180

181 KSize = ((DWORD)pInScan – KStart) / TSIZE;
 

Компилятор выводит следующие предупреждающие сообщения:

SORTMM.C(176) : warning C4311: 'type cast' : pointer truncation from 'TCHAR __based(pInFile) *' to 'DWORD'

SORTMM.C(181) : warning C4311: 'type cast' : pointer truncation from 'TCHAR __based(pInFile) *' to 'DWORD'

Исправления сводятся к использованию DWORD_PTR в качестве типа данных в строке 40 и при приведении типов в строках 176 и 181.

Дополнительные сообщения такого же характера появляются на шаге 2с в конце функции CreateIndexFile. На Web-сайте книги находится видоизмененный файл sortMM64.с, который пригоден как для Win32, так и для Win64, и использование которого позволяет избавиться от появления предупреждающих сообщений.

Предупреждающие сообщения и необходимые изменения, касающиеся других программ

Во всех примерах проектов программ, размещенных на Web-сайте книги, опции установлены таким образом, чтобы в необходимых случаях компилятор выводил предупреждающие сообщения, касающиеся 64-битовых типов данных. Большинство программ компилировались без выдачи предупреждающих сообщений, так что никакие изменения для них не потребовались.

В то же время, программа atouEX (программа 14.2) потребовала нескольких изменений, вызванных необходимостью использования типа данных DWORD_PTR для целочисленной переменной, хранящейся в поле hEvent структуры OVERLAPPED. Это обусловлено тем, что в Win64 размер данных типа HANDLE составляет 64 бита. Необходимые изменения отмечены в листинге программы, находящемся на Web-сайте.

Некоторые предупреждения могут быть проигнорированы. Например, такие функции, как strlen, возвращают значения типа size_t. Длина строки будет часто назначаться переменным типа DWORD, вызывая появление предупреждающих сообщений относительно "потери точности" ("loss of precision"). Во всех практических ситуациях на предупреждения такого рода можно не обращать внимания.

Резюме

64-разрядный Windows API обеспечивает возможность выполнения на Windows-платформах, использующих 64-разрядные процессоры следующего поколения, большинства корпоративных, научных и инженерных приложений с высокими запросами к ресурсам. Предприняв всего лишь нескольких мер предосторожности, можно гарантировать выполнение программ как на платформе Win32, так и на платформе Win64. 

  • Читать дальше
  • 1
  • ...
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: