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

Вновь хочется рассказать об очередной 64\-битной ошибке, найденной нами в одной из программ\. Публиковать в блоге интересные и специфичные ошибки программирования для 64\-битных систем постепенно становится хорошей традицией, которой мы постараемся следовать\.

Описанная ошибка заслуживает внимания своей простотой и можно сказать простодушностью\. Много лет во всех книгах рекомендуют не использовать в коде магические константы, все про это знают, обязательно упоминают в стандартах кодирования и так далее\. Но на практике, волшебные числа возникают в различных участках кода вновь и вновь\.

Рассмотрим пример вызова функции CreateFileMapping в одном из приложений:

```cpp
hFileMapping = CreateFileMapping (
    (HANDLE) 0xFFFFFFFF,
    NULL,
    PAGE_READWRITE,
    (DWORD) 0,
    (DWORD) (szBufIm),
    (LPCTSTR) &FileShareNameMap[0]);
```

Да, да \- вы уже правильно догадались\. Ошибка заключается в использовании константы 0xFFFFFFFF\. Первый аргумент функции CreateFileMapping может иметь значение INVALID\_HANDLE\_VALUE, объявленное следующим образом:

```cpp
#define INVALID_HANDLE_VALUE ((HANDLE)(LONG_PTR)-1)
```

В результате INVALID\_HANDLE\_VALUE действительно совпадает в 32\-битной системе со значением 0xFFFFFFFF\. А вот в 64\-битной системе в функцию CreateFileMapping будет передано значение 0×00000000FFFFFFFF в результате чего система посчитает аргумент некорректным и вернет код ошибки\. Причина в том, что значение 0xFFFFFFFF имеет БЕЗЗАНКОВЫЙ тип \(unsigned int\)\. Значение 0xFFFFFFFF не помещается в тип int и поэтому является типом unsigned\. Это тонкий момент, на который следует обратить внимание при переходе на 64\-битные системы\. Поясним его на примере:

```cpp
void foo(void *ptr)
{
  cout << ptr << endl;
}
int _tmain(int, _TCHAR *[])
{
  cout << "-1\t\t";
  foo((void *)-1);
  cout << "0xFFFFFFFF\t";
  foo((void *)0xFFFFFFFF);
}
```

Результат работы 32\-битного варианта программы:

```cpp
-1              FFFFFFFF
0xFFFFFFFF      FFFFFFFF
```

Результат работы 64\-битного варианта программы:

```cpp
-1              FFFFFFFFFFFFFFFF
0xFFFFFFFF      00000000FFFFFFFF
```

Вы спросите, как все это помнить и как быть уверенным, что подобных ловушек не содержит старый код? Как всегда рекламный ответ \- используйте специализированную систему статического анализа Viva64, включенную в состав [PVS\-Studio](https://pvs-studio.ru/ru/pvs-studio/)\.