From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id CB746383E833; Wed, 13 Jan 2021 13:18:51 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org CB746383E833 From: "tilps at hotmail dot com" To: gcc-bugs@gcc.gnu.org Subject: [Bug c++/98632] Warn about unspecified expression ordering for atomics with non-relaxed memory ordering. Date: Wed, 13 Jan 2021 13:18:51 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: c++ X-Bugzilla-Version: unknown X-Bugzilla-Keywords: diagnostic X-Bugzilla-Severity: normal X-Bugzilla-Who: tilps at hotmail dot com X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-BeenThere: gcc-bugs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-bugs mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 13 Jan 2021 13:18:51 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D98632 --- 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 task_count_; std::atomic 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, b= ut 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 th= e 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 guaran= tee that the ordering is consistent with the memory ordering annotations.=