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

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

28 Авг 2009

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

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

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

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

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

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

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

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-битного варианта программы:

-1              FFFFFFFF
0xFFFFFFFF      FFFFFFFF

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

-1              FFFFFFFFFFFFFFFF
0xFFFFFFFF      00000000FFFFFFFF

Вы спросите, как все это помнить и как быть уверенным, что подобных ловушек не содержит старый код? Как всегда рекламный ответ - используйте специализированную систему статического анализа Viva64, включенную в состав PVS-Studio.

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


Комментарии (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
Ваше сообщение отправлено.

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


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

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