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

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

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

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

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

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

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

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

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

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

Есть прекрасная библиотека компонентов [BCGControlBar](https://bcgsoft.com/bcgcontrolbarpro.htm)\. Наверняка вы про нее слышали, поскольку компоненты компании BCGSoft Ltd включены в Microsoft Visual Studio 2008 Feature Pack\. Так вот, если скачать ознакомительную версию этой библиотеки, установить ее и выполнить поиск слова "WinHelp" по \.h\-файлам\.\.\. то мы увидим, что везде, где якобы перекрыта эта функция, используется параметр DWORD, вместо DWORD\_PTR\. А это означает, что справка в 64\-битной системе в этих классах будет вести себя некорректно\.

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

Что делать? Использовать PVS\-Studio\. Ведь наш анализатор с момента своего создания умеет находить такие ошибки, а справочная система содержит подробный пример \(смотрите описание ошибки [V301](https://pvs-studio.ru/ru/docs/warnings/v301/)\)\.