Читаем Системное программирование в среде Windows полностью

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

Входящий в состав Microsoft Visual Studio 7.0 (.NET) компилятор C++ компании Microsoft может конфигурироваться для выдачи таких сообщений. Для этого достаточно задать в командной строке компилятора опции –Wp64 и –W3. В Visual Studio для установки этих опций потребуется выполнить следующие действия:

• Выберите страницу Project Properties (Свойства проекта).

• Откройте папку C++.

• Щелкните на кнопке General (Общие). 

• Выберите вкладку Detect 64-bit Portability Issues (Определять элементы переноса в 64 разряда) и выберите вариант Yes (/Wp64) (Да (/Wp64)). Оставьте для уровня диагностики (warning level) значение 3.

После этого, в процессе сборки проекта в окне вывода будут отображаться соответствующие предупреждающие сообщения. При построении в Microsoft Visual Studio 7.0 проектов, которые находятся на Web-сайте книги, вывод предупреждающих сообщений конфигурировался именно так, как описано выше.

Код до подготовки к переносу

Большая часть программного кода sortMM.с не приводит к выдаче предупреждающих сообщений, но один участок кода на шаге 6 (см. программу 5.5) вызывает их генерацию. Соответствующий фрагмент кода вместе с номерами строк представлен в программе 16.1. Имейте в виду, что в последующих версиях этой программы номера строк могут поменяться. 

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

54 LPBYTE pXFile = NULL, pX;

55 TCHAR _based (pInFile) *pIn;

130

131 if (!NoPrint)

132  for (iKey = 0; iKey < FsX / RSize; iKey++) {

133   WriteFile(hStdOut, &ChNewLine, TSIZE, &nWrite, NULL);

134

135   /* Приведение типа рХ играет весьма важную роль, поскольку это

136      указатель на байт, а нам нужны четыре байта указателя типа _based. */

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 следующим образом:

Перейти на страницу:

Похожие книги

Programming with POSIX® Threads
Programming with POSIX® Threads

With this practical book, you will attain a solid understanding of threads and will discover how to put this powerful mode of programming to work in real-world applications. The primary advantage of threaded programming is that it enables your applications to accomplish more than one task at the same time by using the number-crunching power of multiprocessor parallelism and by automatically exploiting I/O concurrency in your code, even on a single processor machine. The result: applications that are faster, more responsive to users, and often easier to maintain. Threaded programming is particularly well suited to network programming where it helps alleviate the bottleneck of slow network I/O. This book offers an in-depth description of the IEEE operating system interface standard, POSIX (Portable Operating System Interface) threads, commonly called Pthreads. Written for experienced C programmers, but assuming no previous knowledge of threads, the book explains basic concepts such as asynchronous programming, the lifecycle of a thread, and synchronization. You then move to more advanced topics such as attributes objects, thread-specific data, and realtime scheduling. An entire chapter is devoted to "real code," with a look at barriers, read/write locks, the work queue manager, and how to utilize existing libraries. In addition, the book tackles one of the thorniest problems faced by thread programmers-debugging-with valuable suggestions on how to avoid code errors and performance problems from the outset. Numerous annotated examples are used to illustrate real-world concepts. A Pthreads mini-reference and a look at future standardization are also included.

David Butenhof

Программирование, программы, базы данных
C++: базовый курс
C++: базовый курс

В этой книге описаны все основные средства языка С++ - от элементарных понятий до супервозможностей. После рассмотрения основ программирования на C++ (переменных, операторов, инструкций управления, функций, классов и объектов) читатель освоит такие более сложные средства языка, как механизм обработки исключительных ситуаций (исключений), шаблоны, пространства имен, динамическая идентификация типов, стандартная библиотека шаблонов (STL), а также познакомится с расширенным набором ключевых слов, используемым в .NET-программировании. Автор справочника - общепризнанный авторитет в области программирования на языках C и C++, Java и C# - включил в текст своей книги и советы программистам, которые позволят повысить эффективность их работы. Книга рассчитана на широкий круг читателей, желающих изучить язык программирования С++.

Герберт Шилдт

Программирование, программы, базы данных