>
>
>
V3032. Waiting on this expression is un…


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.

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

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

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' к объявлению переменной:

private volatile int _a;
...

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

Данная диагностика классифицируется как:

Взгляните на примеры ошибок, обнаруженных с помощью диагностики V3032.