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

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

Бесплатная лицензия PVS-Studio для специалистов Microsoft MVP
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

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

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

Ваше сообщение отправлено.

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


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

>
>
>
Урок 14. Паттерн 6. Изменение типа масс…

Урок 14. Паттерн 6. Изменение типа массива

24 Янв 2012

Иногда в программах необходимо (или просто удобно) представлять элементы массива в виде элементов другого типа. Опасное и безопасное приведение типов представлено в следующем коде:

int array[4] = { 1, 2, 3, 4 };
enum ENumbers { ZERO, ONE, TWO, THREE, FOUR };
//safe cast (for MSVC)
ENumbers *enumPtr = (ENumbers *)(array);
cout << enumPtr[1] << " ";
//unsafe cast
size_t *sizetPtr = (size_t *)(array);
cout << sizetPtr[1] << endl;
//Output on 32-bit system: 2 2
//Output on 64-bit system: 2 17179869187

Как видите, результат вывода программы отличается в 32-битном и 64-битном варианте. На 32-битной системе доступ к элементам массива осуществляется корректно, так как размеры типов size_t и int совпадают, и мы видим вывод "2 2".

На 64-битной системе мы получили в выводе "2 17179869187", так как именно значение 17179869187 находится в 1-ом элементе массива sizetPtr (см. рисунок 1). В некоторых случаях именно такое поведение и бывает нужно, но обычно это является ошибкой.

Примечание. Тип enum в компиляторе Visual C++ по умолчанию совпадает размером с типом int, то есть является 32-битным типом. Использование enum другого размера возможно только с помощью расширения, считающимся нестандартным Visual C++. Поэтому приведенный пример корректен в Visual C++, но с точки зрения других компиляторов приведение указателя на элементы int к указателю на элементы enum может быть также некорректным.

14_Pattern_06_Changing_an_arrays_type_ru/image1.png

Рисунок 1 - Расположение элементов массивов в памяти

Исправление описанной ситуации заключается в отказе от опасных приведений типов путем модернизации программы. Другим вариантом является создание нового массива и копирование в него значений из исходного массива.

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

Диагностика

Опасные изменения типа массива диагностируются инструментом PVS-Studio. Анализатор предупреждает о потенциально опасных приведениях типа с помощью диагностических сообщений V114. Соответственно, выводятся предупреждения только о тех конструкциях, которые могут привести к ошибке на 64-битной системе. Например, следующий код является корректным и анализатор не обратит на него внимание программиста:

void **pointersArray;
ptrdiff_t correctID = ((ptrdiff_t *)pointersArray)[index];

Авторы курса: Андрей Карпов (karpov@viva64.com), Евгений Рыжков (evg@viva64.com).

Правообладателем курса "Уроки разработки 64-битных приложений на языке Си/Си++" является ООО "Системы программной верификации". Компания занимается разработкой программного обеспечения в области анализа исходного кода программ. Сайт компании: http://www.viva64.com.

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