Книга: Системное программирование в среде Windows

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

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

Предупреждающие сообщения компилятора для этого фрагмента кода отчетливо демонстрируют неявное предположение о том, что размер указателя составляет 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, и использование которого позволяет избавиться от появления предупреждающих сообщений.

Оглавление книги


Генерация: 1.289. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз