Bug 64658

Summary: std::atomic_init() undefined
Product: gcc Reporter: Jonathan Wakely <redi>
Component: libstdc++Assignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: normal Keywords: rejects-valid
Priority: P3    
Version: 4.9.2   
Target Milestone: 5.0   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2015-01-18 00:00:00

Description Jonathan Wakely 2015-01-18 17:10:52 UTC
#include <atomic>

int main()
{
  std::atomic_int a;
  atomic_init(&a, 0);
}

$ g++ -std=c++11 at.cc
In file included from at.cc:1:0:
/home/jwakely/gcc/5/include/c++/5.0.0/atomic:924:5: warning: inline function ‘void std::atomic_init(std::atomic<_ITp>*, _ITp) [with _ITp = int]’ used but never defined
     atomic_init(atomic<_ITp>* __a, _ITp __i) noexcept;
     ^
/tmp/ccZgPnay.o: In function `main':
/tmp/at.cc:6: undefined reference to `void std::atomic_init<int>(std::atomic<int>*, int)'
collect2: error: ld returned 1 exit status
Comment 1 Jonathan Wakely 2015-01-18 17:22:44 UTC
Although atomic_init doesn't need to be atomic the simplest way to implement it is just with a relaxed store:

--- a/libstdc++-v3/include/std/atomic
+++ b/libstdc++-v3/include/std/atomic
@@ -921,11 +921,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   template<typename _ITp>
     inline void
-    atomic_init(atomic<_ITp>* __a, _ITp __i) noexcept;
+    atomic_init(atomic<_ITp>* __a, _ITp __i) noexcept
+    { __a->store(__i, memory_order_relaxed); }
 
   template<typename _ITp>
     inline void
-    atomic_init(volatile atomic<_ITp>* __a, _ITp __i) noexcept;
+    atomic_init(volatile atomic<_ITp>* __a, _ITp __i) noexcept
+    { __a->store(__i, memory_order_relaxed); }
 
   template<typename _ITp>
     inline void


A better implementation would make atomic_init friend of std::atomic so it can set the private data member directly.
Comment 2 Jonathan Wakely 2015-01-18 17:24:52 UTC
Testcase for 4.9 (which doesn't have the fix for PR64940 that allows std::atomic_int t o be used interchangeably with std::atomic<int>):

#include <atomic>

int main()
{
  std::atomic<int> a;
  atomic_init(&a, 0);
}
Comment 3 Jonathan Wakely 2015-01-20 11:51:16 UTC
Author: redi
Date: Tue Jan 20 11:50:43 2015
New Revision: 219886

URL: https://gcc.gnu.org/viewcvs?rev=219886&root=gcc&view=rev
Log:
	PR libstdc++/64658
	* include/std/atomic (atomic_init): Define.
	* testsuite/29_atomics/atomic/64658.cc: New.

Added:
    trunk/libstdc++-v3/testsuite/29_atomics/atomic/64658.cc
Modified:
    trunk/libstdc++-v3/ChangeLog
    trunk/libstdc++-v3/include/std/atomic
Comment 4 Jonathan Wakely 2015-01-27 12:46:57 UTC
fixed - probably not worth backporting since noone has noticed it's missing (and these functions only really exist because of the original plan for C compatibility, in C++ you can just use the constructor)