Title
Typos in [atomics]?
Status
cd1
Section
[atomics.types.generic]
Submitter
Alberto Ganesh Barbati

Created on 2007-12-28.00:00:00 last changed 171 months ago

Messages

Date: 2010-10-21.18:28:33

Proposed resolution:

Change the synopsis in [atomics.types.generic]:

template <class T> struct atomic<T*> : atomic_address { 
  void store(T*, memory_order = memory_order_seq_cst) volatile;
  T* load( memory_order = memory_order_seq_cst ) volatile;
  T* swap( T*, memory_order = memory_order_seq_cst ) volatile;
  bool compare_swap( T*&, T*, memory_order, memory_order ) volatile;
  bool compare_swap( T*&, T*, memory_order = memory_order_seq_cst ) volatile;

  T* fetch_add(ptrdiff_t, memory_order = memory_order_seq_cst) volatile; 
  T* fetch_sub(ptrdiff_t, memory_order = memory_order_seq_cst) volatile; 

  atomic() = default; 
  constexpr explicit atomic(T*); 
  atomic(const atomic&) = delete; 
  atomic& operator=(const atomic&) = delete; 

  T* operator=(T*) volatile; 
  T* operator++(int) volatile; 
  T* operator--(int) volatile; 
  T* operator++() volatile; 
  T* operator--() volatile; 
  T* operator+=(ptrdiff_t) volatile;
  T* operator-=(ptrdiff_t) volatile; 
};
Date: 2010-10-21.18:28:33

[ Bellevue: ]

The proposed revisions are accepted.

Further discussion: why is the ctor labeled "constexpr"? Lawrence said this permits the object to be statically initialized, and that's important because otherwise there would be a race condition on initialization.

Date: 2007-12-28.00:00:00

in the latest publicly available draft, paper N2641, in section [atomics.types.generic], the following specialization of the template atomic<> is provided for pointers:

template <class T> struct atomic<T*> : atomic_address { 
  T* fetch_add(ptrdiff_t, memory_order = memory_order_seq_cst) volatile; 
  T* fetch_sub(ptrdiff_t, memory_order = memory_order_seq_cst) volatile; 

  atomic() = default; 
  constexpr explicit atomic(T); 
  atomic(const atomic&) = delete; 
  atomic& operator=(const atomic&) = delete; 

  T* operator=(T*) volatile; 
  T* operator++(int) volatile; 
  T* operator--(int) volatile; 
  T* operator++() volatile; 
  T* operator--() volatile; 
  T* operator+=(ptrdiff_t) volatile;
  T* operator-=(ptrdiff_t) volatile; 
};

First of all, there is a typo in the non-default constructor which should take a T* rather than a T.

As you can see, the specialization redefine and therefore hide a few methods from the base class atomic_address, namely fetch_add, fetch_sub, operator=, operator+= and operator-=. That's good, but... what happened to the other methods, in particular these ones:

void store(T*, memory_order = memory_order_seq_cst) volatile;
T* load( memory_order = memory_order_seq_cst ) volatile;
T* swap( T*, memory_order = memory_order_seq_cst ) volatile;
bool compare_swap( T*&, T*, memory_order, memory_order ) volatile;
bool compare_swap( T*&, T*, memory_order = memory_order_seq_cst ) volatile;

By reading paper N2427 "C++ Atomic Types and Operations", I see that the definition of the specialization atomic<T*> matches the one in the draft, but in the example implementation the methods load(), swap() and compare_swap() are indeed present.

Strangely, the example implementation does not redefine the method store(). It's true that a T* is always convertible to void*, but not hiding the void* signature from the base class makes the class error-prone to say the least: it lets you assign pointers of any type to a T*, without any hint from the compiler.

Is there a true intent to remove them from the specialization or are they just missing from the definition because of a mistake?

History
Date User Action Args
2010-10-21 18:28:33adminsetmessages: + msg3711
2010-10-21 18:28:33adminsetmessages: + msg3710
2007-12-28 00:00:00admincreate