# 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 было выполнено.

Выявляемые диагностикой ошибки классифицируются согласно ГОСТ Р 71207–2024 как критические и относятся к типу: Ошибки при работе с многопоточными примитивами (интерфейсами запуска потоков на выполнение, синхронизации и обмена данными между потоками и пр.).

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

CWE-835

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