﻿# V105\. N operand of '?:' operation: implicit type conversion to memsize type\.


> Это правило входит в группу "Диагностика 64\\\-битных ошибок"\\\. Разработка правил этой группы больше не ведётся, и в будущем они могут быть отключены\\\. Если вы используете эти правила, \[свяжитесь с нашей поддержкой\]\(https://pvs\-studio\.ru/ru/about\-feedback/\) — мы поможем найти замену или предложим альтернативное решение\\\.

Анализатор обнаружил потенциально возможную ошибку внутри арифметического выражения, связанную с неявным приведением к типу memsize\. Ошибка переполнения может быть связана с изменением допустимого интервала значений переменных, входящих в выражение\. Данное предупреждение практически эквивалентно предупреждению V104, за тем исключением, что неявное приведение типа возникает за счет использования операции '?:'\. 

Приведем пример неявного приведения типов при использовании операции:

```cpp
int i32;
float f = b != 1 ? sizeof(int) : i32;
```

В арифметическом выражении используется тернарная операция '?:', имеющая три операнда:

* b \!\= 1 \- первый операнд;
* sizeof\(int\) \- второй операнд;
* i32 \- третий операнд\.

Результатом выражения "b \!\= 1 ? sizeof\(int\) : i32" является значение типа 'size\_t', которое затем преобразуется в значение типа 'float'\. Таким образом, неявное приведение типа осуществляется для 3\-его операнда операции '?:'\.

Рассмотрим пример некорректного кода:

```cpp
bool useDefaultVolume;
size_t defaultVolume;
unsigned width, height, depth;
...
size_t volume = useDefaultVolume ?
                        defaultVolume :
                        width * height * depth;
```

Предположим, мы разрабатываем приложение численного моделирования, для которого требуется трехмерная счетная область\. Количество используемых счетных элементов определяется в зависимости от значения переменной 'useDefaultSize' и задается по умолчанию или произведением длинны, высоты и глубины счетной области\. На 32\-битной платформе объем уже выделенной памяти не может превышать 2\-3 Гб \(в зависимости от версии ОС Windows\) и, соответственно, результат выражения "width \* height \* depth" всегда будет корректен\. На 64\-битной платформе, пользуясь возможностью работать с большим объемом памяти, количество счетных элементов может превысить значение 'UINT\_MAX' \(4 Гб\)\. В этом случае произойдет переполнение при вычислении выражения "width \* height \* depth", так как результат этого выражения имеет тип 'unsigned'\.

Исправление кода может заключаться в изменении типа переменных 'width', 'height' и 'depth' на memsize тип, как показано ниже:

```cpp
...
size_t width, height, depth;
...
size_t volume = useDefaultVolume ?
                        defaultVolume :
                        width * height * depth;
```

Или использовании [явного приведения типов](https://pvs-studio.ru/ru/blog/terms/0015/):

```cpp
unsigned width, height, depth;
...
size_t volume = useDefaultVolume ?
                        defaultVolume :
         size_t(width) * size_t(height) * size_t(depth);
```

Дополнительно мы рекомендуем изучить описание аналогичного предупреждения [V104](https://pvs-studio.ru/ru/docs/warnings/v104/), где можно ознакомиться с другими эффектами неявного приведения к типу memsize\.

Дополнительные материалы по данной теме:

1. 64\-битные уроки\. Урок 17\. Паттерн 9\. [Смешанная арифметика](https://pvs-studio.ru/ru/blog/lessons/0017/)\.