https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98632
--- Comment #2 from tilps at hotmail dot com --- *rough sketch* class TaskConsumer { void run() { if (taken_count_.load(std::memory_order_acquire) < task_count_.load(std::memory_order_acquire)) { taken_count_.fetch_add(1, std::memory_order_acq_rel); // ... handle the new task... } } void addTask() { task_count_.fetch_add(1, std::memory_order_acq_rel); } void reset() { task_count_.store(0, std::memory_order_release); taken_count_.store(0, std::memory_order_release); } std::atomic<int> task_count_; std::atomic<int> taken_count_; }; The above is not a 'complete' code sample, just illustrative. One thread is calling 'run' in a loop. Other thread calls reset, then add task some number of times. Waits until it knows the first thread has done all tasks (not covered in the code above, but assume that it is thread-safe and establishes acquire/release ordering as appropriate), then calls reset again and repeats the process. In order for the 'if' statement to behave correctly taken count must be read before task count. If task count is read first it can read the value in task_count_ before reset, but the taken_count_ value after reset. If an optimizer (not necessarily an existing gcc one) decides to reorder the if statement because the standard says order is unspecified and it notices that task_count_ is an earlier memory address to taken_count_ and presumes reordering might give a small performance increase due to sequential memory access and cpu prefetching assumptions... then the code breaks. Thus I would like a warning pointing at that if statement with wording along the lines of: C++ standard does not guarantee ordering of evaluation in this expression, thus the order of atomic operations with non-relaxed memory ordering in this expression is unspecified. Extract them into separate expressions to guarantee that the ordering is consistent with the memory ordering annotations.