Здесь некоторый код C++, к которому получают доступ от нескольких потоков параллельно. Это имеет критический раздел:
lock.Acquire();
current_id = shared_id;
// small amounts of other code
shared_id = (shared_id + 1) % max_id;
lock.Release();
// do something with current_id
Класс переменной блокировки является оберткой вокруг взаимоисключающей реализации POSIX. Из-за операций модуля не возможно использовать атомарные операции.
Действительно ли возможно, что gcc компилятор с флагом O3 оптимизирует код так, чтобы присвоение current_id было перемещено перед блокировкой?
Можно скомпилировать с O3!
Компилятор никогда не будет оптимизировать по функциональному вызову, если только функция не помечена как чистая с использованием функций-атрибутов.
Функции METEX не являются чистыми, поэтому абсолютно безопасно использовать их с O3.
Обычно компилятор не должен делать таких вредоносных оптимизаций. Если вы все еще не уверены, можно использовать ключевое слово volatile для предотвращения оптимизаций на этих переменных id.