Для получения триального ключа
заполните форму ниже
Team License (базовая версия)
Enterprise License (расширенная версия)
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

** На сайте установлена reCAPTCHA и применяются
Политика конфиденциальности и Условия использования Google.
Запросите информацию о ценах
Новая лицензия
Продление лицензии
--Выберите валюту--
USD
EUR
GBP
RUB
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

** На сайте установлена reCAPTCHA и применяются
Политика конфиденциальности и Условия использования Google.
Для получения лицензии для вашего открытого
проекта заполните, пожалуйста, эту форму
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

** На сайте установлена reCAPTCHA и применяются
Политика конфиденциальности и Условия использования Google.
Для получения лицензии для вашего открытого
проекта заполните, пожалуйста, эту форму
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

** На сайте установлена reCAPTCHA и применяются
Политика конфиденциальности и Условия использования Google.
Мне интересно попробовать плагин на:
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

** На сайте установлена reCAPTCHA и применяются
Политика конфиденциальности и Условия использования Google.
Ваше сообщение отправлено.

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


Если вы так и не получили ответ, пожалуйста, проверьте папку
Spam/Junk и нажмите на письме кнопку "Не спам".
Так Вы не пропустите ответы от нашей команды.

>
>
>
V220. Suspicious sequence of types cast…
Сообщения PVS-Studio
Диагностики общего назначения (General Analysis, C++)
Диагностики общего назначения (General Analysis, C#)
Диагностики общего назначения (General Analysis, Java)
Диагностика микро-оптимизаций (C++)
Диагностика 64-битных ошибок (Viva64, C++)
Cтандарт MISRA
Стандарт AUTOSAR
Дополнительная информация
Оглавление

V220. Suspicious sequence of types castings: memsize -> 32-bit integer -> memsize.

05 Мар 2015

Предупреждение информирует о наличии странной последовательности приведений типа. Memsize-тип явно приводится к 32-битному целочисленному типу. А затем тут же вновь явно или неявно приводится к memsize-типу. Такая последовательность приведений приводит к потере значений старших бит. Как правило, это свидетельствует о наличии серьезной ошибки.

Рассмотрим пример:

char *p1;
char *p2;
ptrdiff_t n;
...
n = int(p1 - p2);

Здесь присутствует лишнее приведение к типу 'int'. Оно не нужно и может послужить причиной сбоя, если в 64-битной программе указатели p1 и p2 будут отстоять друг от друга больше чем на INT_MAX элементов.

Корректный вариант кода:

char *p1;
char *p2;
ptrdiff_t n;
...
n = p1 - p2;

Рассмотрим другой пример:

BOOL SetItemData(int nItem, DWORD_PTR dwData);
...
CItemData *pData = new CItemData;
...
CListCtrl::SetItemData(nItem, (DWORD)pData);

Этот код приведёт к ошибке, если объект типа CItemData будет создан за пределами четырех младших гигабайт памяти. Корректный вариант кода:

BOOL SetItemData(int nItem, DWORD_PTR dwData);
...
CItemData *pData = new CItemData;
...
CListCtrl::SetItemData(nItem, (DWORD_PTR)pData);

Следует учитывать, что анализатор не выдаёт предупреждение, если конвертации подвергается такие типы данных, как HANDLE, HWND, HCURSOR и так далее. Хотя, по сути, это указатели (void *), их значения всегда вмещаются в младшие 32-бита. Это сделано специально, чтобы эти дескрипторы (handles) можно было передавать между 32-битными и 64-битными процессами. Подробнее: Как корректно привести указатель к int в 64-битной программе?

Рассмотрим пример:

typedef void * HANDLE;
HANDLE GetHandle(DWORD nStdHandle);
int _open_osfhandle(intptr_t _OSFileHandle, int _Flags);
....
int fh = _open_osfhandle((int)GetHandle(sh), 0);

Здесь имеет место преобразование вида:

HANDLE -> int -> intptr_t

Т.е. вначале указатель превращается в 32-битный тип 'int', а замет расширяется до 'intptr_t'. Это не очень красиво. Лучше было бы написать "(intptr_t)GetHandle(STD_OUTPUT_HANDLE)". Однако, никакой ошибки здесь и нет, так как значения типа HANDLE помещаются в 'int'. Поэтому анализатор промолчит.

Если будет написано:

int fh = _open_osfhandle((unsigned)GetHandle(sh), 0);

То анализатор выдаст предупреждение. Смешивание знаковых и беззнаковых типов всё портит. Представим, что GetHandle() вернёт INVALID_HANDLE_VALUE. Это значение задано в системных заголовочных файлах следующим образом.

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

Посмотрим, что получитcя при преобразовании (intptr_t)(unsigned)((HANDLE)(LONG_PTR)-1):

-1 -> 0xffffffffffffffff -> HANDLE -> 0xffffffffu -> 0x00000000fffffffff

Значение -1 превратилось в 4294967295. Это может быть не учтено программистом и программа может работать некорректно, если функция GetHandle() вернёт INVALID_HANDLE_VALUE. Поэтому, для второго случая анализатор выдаст предупреждение.

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