﻿# V3032\. Waiting on this expression is unreliable, as compiler may optimize some of the variables\. Use volatile variable\(s\) or synchronization primitives to avoid this\.

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

Приведём пример:

```cpp
private int _a;
public void Foo()
{
    var task = new Task(Bar);
    task.Start();
    Thread.Sleep(10000);
    _a = 0;
    task.Wait();
}

public void Bar()
{
    _a = 1;
    while (_a == 1);        
}
```



Если выполнить данный код скомпилированный в Debug конфигурации, программа завершится корректно\. Однако, если скомпилировать этот же код под Release, программа зависнет на цикле while\. Причина такого поведения в том, что компилятор "закэширует" значение переменной '\_a'\.

Из\-за подобного различия Debug\-версии и Release\-версии могут возникать сложные и трудно детектируемые ошибки\. Путей корректировки данной ситуации несколько\. Если эта переменная и впрямь используется для контроля логики многопоточной программы, то лучше использовать специализированные средства синхронизации, такие как мьютексы и семафоры\. Другим вариантом исправления может стать добавление модификатора 'volatile' к объявлению переменной:

```cpp
private volatile int _a;
...
```

Обратите внимание на то, что даже после такой правки код примера не станет полностью безопасным, т\.к\. нет гарантии, что Bar\(\) начнёт выполняться раньше, чем переменной '\_a' будет присвоено значение 0\. Мы привели данный пример лишь чтобы продемонстрировать потенциально опасную ситуацию, связанную с оптимизациями компилятора\. Для того, чтобы сделать код примера полностью безопасным, необходимо добавить, например, дополнительную синхронизацию перед выражением \_a \= 0, которая гарантирует, что выражение \_a \= 1 было выполнено\.