14 pattern 06_changing_an_arrays_type_ru

3

Click here to load reader

Upload: tatyanazaxarova

Post on 12-Jun-2015

187 views

Category:

Technology


0 download

DESCRIPTION

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

TRANSCRIPT

Page 1: 14 pattern 06_changing_an_arrays_type_ru

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

массива

Иногда в программах необходимо (или просто удобно) представлять элементы массива в виде

элементов другого типа. Опасное и безопасное приведение типов представлено в следующем

коде:

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 может быть также некорректным.

Page 2: 14 pattern 06_changing_an_arrays_type_ru

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

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

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

него значений из исходного массива.

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

идентификаторов пытаются использовать значения указателей.

Диагностика

Опасные изменения типа массива диагностируются инструментом PVS-Studio. Анализатор

предупреждает о потенциально опасных приведениях типа с помощью диагностических

сообщений V114. Соответственно, выводятся предупреждения только о тех конструкциях, которые

могут привести к ошибке на 64-битной системе. Например, следующий код является корректным

и анализатор не обратит на него внимание программиста:

void **pointersArray;

Page 3: 14 pattern 06_changing_an_arrays_type_ru

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

Авторы курса: Андрей Карпов ([email protected]), Евгений Рыжков ([email protected]).

Правообладателем курса "Уроки разработки 64-битных приложений на языке Си/Си++"

является ООО "Системы программной верификации". Компания занимается разработкой

программного обеспечения в области анализа исходного кода программ. Сайт компании:

http://www.viva64.com.

Контактная информация: e-mail: [email protected], 300027, г. Тула, а/я 1800.