Мы используем куки, чтобы пользоваться сайтом было удобно.
Хорошо
to the top
>
>
>
Проблемы 64-битного кода в реальных про…

Проблемы 64-битного кода в реальных программах: виртуальные функции

15 Сен 2009

Об одной проблеме при миграции кода на 64-битные системы, связанной с некорректной перегрузкой виртуальных функций мы писали в наших статьях уже давно. Например, наша статья "20 ловушек переноса Си++ - кода на 64-битную платформу" вышла в марте 2007 года (хотя ничуть не утратила актуальности). В ней было описание проблемы с виртуальными функциями.

Суть проблемы заключается в следующем. С незапамятных времен в библиотеке MFC есть класс CWinApp, в котором имеется функция WinHelp:

class CWinApp {
  ...
  virtual void WinHelp(DWORD dwData, UINT nCmd);
};

Для показа собственной справки в пользовательском приложении необходимо было эту функцию перекрыть:

class CSampleApp : public CWinApp {
  ...
  virtual void WinHelp(DWORD dwData, UINT nCmd);
};

И все было прекрасно до тех пор, пока не появились 64-битные системы. Тогда разработчикам MFC пришлось поменять интерфейс функции WinHelp (и некоторых других) так:

class CWinApp {
  ...
  virtual void WinHelp(DWORD_PTR dwData, UINT nCmd);
};

В 32-битном режиме типы DWORD_PTR и DWORD совпадали, а вот в 64-битном... Естественно разработчики пользовательского приложения тоже должны были сменить тип на DWORD_PTR для корректной перегрузки, но компилятор про это не говорил, и ошибка выявлялась только на этапе тестирования, когда справочная система вела себя "загадочно". За подробностями я отсылаю читателя к упомянутой выше статье.

Вспомнить эту ошибку меня заставил тот факт, что сегодня, в конце 2009 года эта ошибка до сих пор есть в коде реальных приложений. Сомневаетесь?

Есть прекрасная библиотека компонентов BCGControlBar. Наверняка вы про нее слышали, поскольку компоненты компании BCGSoft Ltd включены в Microsoft Visual Studio 2008 Feature Pack. Так вот, если скачать ознакомительную версию этой библиотеки, установить ее и выполнить поиск слова "WinHelp" по .h-файлам... то мы увидим, что везде, где якобы перекрыта эта функция, используется параметр DWORD, вместо DWORD_PTR. А это означает, что справка в 64-битной системе в этих классах будет вести себя некорректно.

Неужели подобная ошибка может до сих пор быть в коде такой известной библиотеки? Я думаю дело в том, что клиентам компании доступны исходные коды этой библиотеки и клиенты всегда могут поправить эти коды. Кроме того, в настоящее время функция WinHelp используется очень редко. Намного чаще используется HtmlHelp. А она-то в BCGControlBar имеет правильный параметр DWORD_PTR. Однако факт остается фактом. Ошибка есть во вполне реальном коде и компилятор ее не обнаружит.

Что делать? Использовать PVS-Studio. Ведь наш анализатор с момента своего создания умеет находить такие ошибки, а справочная система содержит подробный пример (смотрите описание ошибки V301).

Популярные статьи по теме


Комментарии (0)

Следующие комментарии next comments
close comment form
close form

Заполните форму в два простых шага ниже:

Ваши контактные данные:

Шаг 1
Поздравляем! У вас есть промокод!

Тип желаемой лицензии:

Шаг 2
Team license
Enterprise license
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности
close form
Запросите информацию о ценах
Новая лицензия
Продление лицензии
--Выберите валюту--
USD
EUR
RUB
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Бесплатная лицензия PVS‑Studio для специалистов Microsoft MVP
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Для получения лицензии для вашего открытого
проекта заполните, пожалуйста, эту форму
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Мне интересно попробовать плагин на:
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
check circle
Ваше сообщение отправлено.

Мы ответим вам на


Если вы так и не получили ответ, пожалуйста, проверьте, отфильтровано ли письмо в одну из следующих стандартных папок:

  • Промоакции
  • Оповещения
  • Спам