Урок 6. Ошибки в 64-битном коде

259 views

Published on

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

Published in: Technology, Business
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
259
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
3
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Урок 6. Ошибки в 64-битном коде

  1. 1. Урок 6. Ошибки в 64-битном кодеИсправление всех ошибок компиляции и предупреждений не будет означать работоспособность64-битного приложения. И именно описанию и диагностике 64-битных ошибок будет посвященаосновная часть уроков. Также не надейтесь на помощь ключа /Wp64, который многими часто безоснований преподносится при обсуждениях в форумах как чудесное средство поиска 64-битныхошибок.Ключ /Wp64Ключ /Wp64 позволяет программисту найти некоторые проблемы, которые могут возникнуть прикомпиляции кода для 64-битных систем. Проверка заключается в том, что типы, которыеотмечены в 32-битном коде ключевым словом __w64 интерпретируются при проверке как 64-битные типы.Например, пусть мы имеем следующий код:typedef int MyInt32;#ifdef _WIN64 typedef __int64 MySSizet;#else typedef int MySSizet;#endifvoid foo() { MyInt32 value32 = 10; MySSizet size = 20; value32 = size;}Выражение "value32 = size;" на 64-битной системе приведет к урезанию значения, а,следовательно, к потенциальной ошибке. Мы хотим это диагностировать. Но при компиляции 32-битного приложения, все корректно и мы не получим предупреждения.Для того чтобы подготовиться к 64-битным системам, нам следует добавить ключ /Wp64 ивставить ключевое слово __w64 при описании типа MySSizet в 32-битном варианте. В результатекод станет выглядеть так:typedef int MyInt32;#ifdef _WIN64 typedef __int64 MySSizet;
  2. 2. #else typedef int __w64 MySSizet; // Add __w64 keyword#endifvoid foo() { MyInt32 value32 = 10; MySSizet size = 20; value32 = size; // C4244 64-bit int assigned to 32-bit int}Теперь мы получим предупреждение C4244, которое поможет подготовиться к переносу кода на64-битную платформу.Обратите внимание, что для 64-битного режима компиляции ключ /Wp64 игнорируется, так каквсе типы уже имеют необходимый размер, и компилятор произведет необходимые проверки. Тоесть при компиляции 64-битной версии даже с выключенным ключом /Wp64 мы получимпредупреждение C4244.Таким образом, ключ /Wp64 помогал разработчикам при работе еще с 32-битнымиприложениями немного подготовиться к 64-битному компилятору. Все предупреждения, которыеобнаруживает /Wp64, превратятся при сборке 64-битного кода в ошибки компиляции или такжеостанутся предупреждениями. Но никакой дополнительной помощи в выявлении ошибок ключ/Wp64 не дает.Кстати, в Visual Studio 2008 ключ /Wp64 считается устаревшим, поскольку уже давно поракомпилировать 64-битные приложения, а не продолжать готовиться к этому.64-битные ошибкиГоворя о 64-битных ошибках, мы будем понимать под ними такие ситуации, когда фрагмент кода,успешно работавший в 32-битном варианте, приводит к возникновению ошибки послекомпиляции 64-битной версии приложения. Наиболее часто 64-битные ошибки проявляют себя вследующих участках кода: • код, основанный на некорректных представлениях о размере типов (например, что размер указателя всегда равен 4 байтам); • код обрабатывающий большие массивы, размер которых на 64-битных системах превышает 2 гигабайта; • код записи и чтения данных; • код с битовыми операциями; • код со сложной адресной арифметикой; • старый код; • и так далее.В конечном итоге все ошибки в коде, проявляющие себя при компиляции для 64-битных систем,связаны с неточным следованием идеологии стандарта языка Си/Си++. Однако мы считаем
  3. 3. нерациональным придерживаться позиции "пишите корректные программы и тогда в них небудет 64-битных ошибок". С этим нельзя поспорить, но и пользы от такой рекомендации дляреальных проектов мало. В мире накоплено огромное количество кода на языке Си/Си++,который писался десятилетиями. Задача этих уроков сформулировать все 64-битные ошибки ввиде набора паттернов, которые помогут выявить дефекты и дать рекомендации по ихустранению.Примеры 64-битных ошибокО 64-битных ошибках еще будет сказано очень много. Но приведем 2 примера, чтобы стало болеепонятно, что могут представлять из себя эти ошибки.Пример использования магической константы 4, которая служит размером указателя, чтонекорректно для 64-битного кода. Обратите внимание, данный код успешно функционировал в32-битном варианте и не диагностируется компилятором как опасный.size_t pointersCount = 100;int **arrayOfPointers = (int **)malloc(pointersCount * 4);Следующий пример демонстрирует ошибку в механизме чтения данных. Данный код корректноработает в 32-битном режиме и не обнаруживается компилятором. Однако такой коднекорректно прочитает данные сохраненные 32-битной версией программы.size_t PixelCount;fread(&PixelCount, sizeof(PixelCount), 1, inFile);Комментарий искушенным программистамХочется заранее сделать комментарий о паттернах 64-битных ошибок и их примерах, которымбудет уделено большое количество уроков. Нам часто возражают, что это на самом деле неошибки 64-битности, а ошибки недостаточно корректно и недостаточно переносимо написанногокода. И что многие ошибки можно обнаружить не только при переходе на 64-битную архитектуру,но и просто на архитектуру с иными размерами базовых типов.Да, это именно так! Мы помним про это. Но мы не ставим целью рассматривать переносимостькода вообще. В этих уроках мы хотим решить конкретную частную задачу, а именно помочьразработчикам в освоении 64-битных платформ, которые получают все большее распространение.Говоря о паттернах 64-битных ошибках, мы будем рассматривать примеры кода, которыйкорректно функционирует на 32-битных системах, но может приводить к сбою при его переносена 64-битную архитектуру.Авторы курса: Андрей Карпов (karpov@viva64.com), Евгений Рыжков (evg@viva64.com).Правообладателем курса "Уроки разработки 64-битных приложений на языке Си/Си++"является ООО "Системы программной верификации". Компания занимается разработкойпрограммного обеспечения в области анализа исходного кода программ. Сайт компании:http://www.viva64.com.
  4. 4. Контактная информация: e-mail: support@viva64.com, 300027, г. Тула, а/я 1800.

×