﻿# V708\. Dangerous construction is used: 'm\[x\] \= m\.size\(\)', where 'm' is of 'T' class\. This may lead to undefined behavior\.

Анализатор обнаружил в коде программы случай неопределённого поведения, связанного с контейнерами типа map или схожими с ним\.

Пример некорректного кода:

```cpp
std::map<size_t, size_t> m;
....
m[0] = m.size();
```

Этот пример приводит к неопределённому поведению, поскольку порядок вычисления операндов у оператора присваивания не определён\. В случае, если в объекте уже существует элемент, ассоциированный с нулём, то проблем не возникнет\. Однако в случае его отсутствия действия программы могут пойти по двум различным сценариям в зависимости от версии компилятора, операционной системы и так далее\.

Предположим, что компилятор сначала вычисляет правый операнд и лишь потом – левый операнд операции присваивания\. Поскольку контейнер пуст, m\.size\(\) возвращает ноль\. Затем с нулём ассоциируется ноль\. В итоге имеем, что m\[0\] \=\= 0\.

Теперь предположим, что компилятор сначала вычисляет левый операнд и лишь потом – правый\. Сначала будет взят m\[0\]\. Поскольку с нулём ничего не ассоциировано, будет создана пустая ассоциация\. Затем вычисляется m\.size\(\)\. Поскольку контейнер уже не пуст, m\.size\(\) возвращает единицу\. После этого единица ассоциируется с нулём\. В итоге имеем, что m\[0\] \=\= 1\.

Правильным решением для исправления кода будет использования временной переменной и заранее связать какое\-то значение с нулём:

```cpp
std::map<size_t, size_t> m;
....
m[0] = 0;
const size_t mapSize = m.size();
m[0] = mapSize;
```

Несмотря на то, что данная ситуация может возникать достаточно редко в реальном коде, она опасна тем, что фрагмент кода, приводящий к неопределённому поведению, часто очень сложно выявить\.