Мы используем куки, чтобы пользоваться сайтом было удобно.
Хорошо
to the top
menu mobile close menu
Проверка проектов
Дополнительная информация
toggle menu Оглавление

V1091. The pointer is cast to an integer type of a larger size. Casting pointer to a type of a larger size is an implementation-defined behavior.

07 Сен 2022

Анализатор обнаружил приведение указателя к интегральному типу большего размера. Результат может отличаться от ожидаемого программистом.

Согласно стандартам C и C++, результат такого выражения зависит от реализации. Ожидаемый программистом результат в большинстве реализаций будет совпадать тогда, когда указатель приводится к интегральному типу того же размера.

Рассмотрим следующий синтетический пример:

void foo()
{
  const void *ptr = reinterpret_cast<const void *>(0x80000000);
  uint64_t ui64 = reinterpret_cast<uint64_t>(ptr); // <=
}

В примере указатель 'ptr' преобразуется в тип 'uint64_t', имеющий размер 8 байт. На 32-битной платформе размер указателя равен 4 байтам. Результат такого преобразования зависит от реализации компилятора.

Так, если используется компилятор GCC или MSVC, то в переменную 'ui64' будет записано число 0xffff'ffff'8000'0000. В то же время Clang запишет число 0x0000'0000'8000'0000.

Чтобы преобразовать 32-битный указатель в 64-битное число и избежать поведения, определённого реализацией, нужно сделать следующее:

  • Преобразовать 32-битный указатель к 32-битному числу
  • Преобразовать полученное 32-битное число к 64-битному числу

Для исправления сначала преобразуем указатель к 'uintptr_t'. Это целочисленный беззнаковый тип, размер которого всегда равен размеру указателя. Затем полученное 32-битное число преобразуем к 64-битному. Исправленный код:

void foo()
{
  const void *ptr = reinterpret_cast<const void*>(0x80000000);
  uint64_t ui64 = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(ptr));
}

Данная диагностика классифицируется как: