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

Андрей Карпов
Статей: 671

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

Явные приведения типа часто маскируют ошибки, связанные с изменением типа указателя. Одной из таких ошибок является превращение указателя на 32-битные объекты в указатель на 64-битные объекты.

Рассмотрим пример, присланный пользователями нашего инструмента PVS-Studio (Viva64). Ошибка проявляет себя после переноса кода на 64-битную версию Windows:

void ProcessTime(long * pTime)
{
  time((time_t *)pTime);
}

В 32-битной программе использовался 32-битный вариант типа time_t. В 64-битной системе для использования доступен только 64-битный вариант типа time_t. Это явно указано в заголовочном файле crtdefs.h:

#ifdef  _USE_32BIT_TIME_T
#ifdef  _WIN64
#error You cannot use 32-bit time_t (_USE_32BIT_TIME_T) with _WIN64
#endif
#ifdef _USE_32BIT_TIME_T
typedef __time32_t time_t;
#else
typedef __time64_t time_t;
#endif

Продемонстрированное явное изменения типа указателя может привести к неопределенному поведению программы или ее аварийному завершению. Поиск подобных ошибок затруднен, поскольку конструкция явного приведения типа подавляет предупреждения компилятора (см. запись: "Поиск ошибок явного приведения типа в 64-битных программах").

Помочь обнаружить такие ошибки может диагностическое сообщение "V114. Dangerous explicit type pointer conversion", выдаваемое анализатором кода PVS-Studio (Viva64) при проверке 64-битных проектов. Помимо показанного примера, диагностическое сообщение V114 позволяет обнаружить родственную ошибку, связанную с изменением типа массива:

int array[4] = { 1, 2, 3, 4 };
size_t *sizetPtr = (size_t *)(array);
cout << sizetPtr[1] << endl;
Результат работы на 32-битной системе: 2
Результат работы на 64-битной системе: 17179869187