<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 3418: Deprecated free functions in &lt;atomic&gt;</title>
<meta property="og:title" content="Issue 3418: Deprecated free functions in &lt;atomic&gt;">
<meta property="og:description" content="C++ library issue. Status: New">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue3418.html">
<meta property="og:type" content="website">
<meta property="og:image" content="http://cplusplus.github.io/LWG/images/cpp_logo.png">
<meta property="og:image:alt" content="C++ logo">
<style>
  p {text-align:justify}
  li {text-align:justify}
  pre code.backtick::before { content: "`" }
  pre code.backtick::after { content: "`" }
  blockquote.note
  {
    background-color:#E0E0E0;
    padding-left: 15px;
    padding-right: 15px;
    padding-top: 1px;
    padding-bottom: 1px;
  }
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  table.issues-index { border: 1px solid; border-collapse: collapse; }
  table.issues-index th { text-align: center; padding: 4px; border: 1px solid; }
  table.issues-index td { padding: 4px; border: 1px solid; }
  table.issues-index td:nth-child(1) { text-align: right; }
  table.issues-index td:nth-child(2) { text-align: left; }
  table.issues-index td:nth-child(3) { text-align: left; }
  table.issues-index td:nth-child(4) { text-align: left; }
  table.issues-index td:nth-child(5) { text-align: center; }
  table.issues-index td:nth-child(6) { text-align: center; }
  table.issues-index td:nth-child(7) { text-align: left; }
  table.issues-index td:nth-child(5) span.no-pr { color: red; }
  @media (prefers-color-scheme: dark) {
     html {
        color: #ddd;
        background-color: black;
     }
     ins {
        background-color: #225522
     }
     del {
        background-color: #662222
     }
     a {
        color: #6af
     }
     a:visited {
        color: #6af
     }
     blockquote.note
     {
        background-color: rgba(255, 255, 255, .10)
     }
  }
</style>
</head>
<body>
<hr>
<p><em>This page is a snapshot from the LWG issues list, see the <a href="lwg-active.html">Library Active Issues List</a> for more information and the meaning of <a href="lwg-active.html#New">New</a> status.</em></p>
<h3 id="3418"><a href="lwg-active.html#3418">3418</a>. Deprecated free functions in <code>&lt;atomic&gt;</code></h3>
<p><b>Section:</b> 32.5.9 <a href="https://wg21.link/atomics.nonmembers">[atomics.nonmembers]</a> <b>Status:</b> <a href="lwg-active.html#New">New</a>
 <b>Submitter:</b> Alisdair Meredith <b>Opened:</b> 2020-03-19 <b>Last modified:</b> 2020-09-06</p>
<p><b>Priority: </b>3
</p>
<p><b>View all issues with</b> <a href="lwg-status.html#New">New</a> status.</p>
<p><b>Discussion:</b></p>
<p>
Paper <a href="https://wg21.link/p1831r1">P1831R1</a> deprecated the <code>volatile</code>-qualified 
member functions of <code>std::atomic</code> unless <code>is_always_lock_free</code> is <code>true</code>.  
32.5.9 <a href="https://wg21.link/atomics.nonmembers">[atomics.nonmembers]</a> maps free functions calls, declared in the <code>&lt;atomic&gt;</code> 
header, to those member functions, but does not deprecate them under the same circumstances.
<p/>
I have confirmed with the paper author that the intended design was to deprecate these too, 
but currently we have no wording.
</p>

<p><i>[2020-03-29; Daniel provides wording]</i></p>

<p>
The suggested wording changes for 32.5.9 <a href="https://wg21.link/atomics.nonmembers">[atomics.nonmembers]</a> attempts to make clear that 
any of the specification elements of the member function (including but not restricted to <i>Constraints:</i>
elements) are also imposed on the corresponding non-member function template. According to 
16.3.2.4 <a href="https://wg21.link/structure.specifications">[structure.specifications]</a>, the wording "the semantics of the code sequence are determined 
by the <i>Constraints</i>,[&hellip;], and <i>Error conditions</i> specified for the function invocations contained in 
the code sequence." should realize the wanted effect. The advantage of this more general wording form is
that we don't need to to worry in case that in the future <i>Constraints:</i> elements of the member 
functions are modified.
</p>

<p><i>[2020-03-30; Tim improves wording]</i></p>


<p><i>[2020-04-25 Issue Prioritization]</i></p>

<p>Priority to 3 after reflector discussion.</p>


<p id="res-3418"><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/n4861">N4861</a>.
</p>

<ol>
<li><p>Modify 32.5.9 <a href="https://wg21.link/atomics.nonmembers">[atomics.nonmembers]</a> as indicated:</p>

<blockquote>
<p>
-1- A non-member function template whose name matches the pattern <code>atomic_<i>f</i></code> or the 
pattern <code>atomic_<i>f</i>_explicit</code> invokes the member function <code><i>f</i></code>, with the 
value of the first parameter as the object expression and the values of the remaining parameters 
(if any) as the arguments of the member function call, in order. An argument for a parameter of 
type <code>atomic&lt;T&gt;::value_type*</code> is dereferenced when passed to the member function call. 
If no such member function exists, the program is ill-formed. <ins>Otherwise, a call to such
a function template has effects equivalent to (16.3.2.4 <a href="https://wg21.link/structure.specifications">[structure.specifications]</a>) the effective 
code sequence containing the <code><i>f</i></code> invocation specified in this subclause.</ins>
</p>
</blockquote>
</li>

<li><p>Modify D.23.2 <a href="https://wg21.link/depr.atomics.volatile">[depr.atomics.volatile]</a>, annex D, as indicated:</p>

<blockquote>
<p>
If an atomic specialization has one of the following overloads, then that overload participates in overload
resolution even if <code>atomic&lt;T&gt;::is_always_lock_free</code> is <code>false</code>:
</p>
<blockquote>
<pre>
void store(T desired, memory_order order = memory_order::seq_cst) volatile noexcept;
[&hellip;]
T* fetch_<i>key</i>(ptrdiff_t operand, memory_order order = memory_order::seq_cst) volatile noexcept;
</pre>
</blockquote>
<p>
<ins>In addition, the following non-member function templates participate in overload
resolution even if <code>atomic&lt;T&gt;::is_always_lock_free</code> is <code>false</code>:</ins> 
</p>
<blockquote>
<pre>
<ins>template&lt;class T&gt;
  void atomic_store(volatile atomic&lt;T&gt;*, typename atomic&lt;T&gt;::value_type) noexcept;
template&lt;class T&gt;
  T atomic_load(const volatile atomic&lt;T&gt;*) noexcept;
template&lt;class T&gt;
  T atomic_load_explicit(const volatile atomic&lt;T&gt;*, memory_order) noexcept;
template&lt;class T&gt;
  T atomic_exchange(volatile atomic&lt;T&gt;*, typename atomic&lt;T&gt;::value_type) noexcept;
template&lt;class T&gt;
T atomic_exchange_explicit(volatile atomic&lt;T&gt;*, typename atomic&lt;T&gt;::value_type,
  memory_order) noexcept;
template&lt;class T&gt;
  bool atomic_compare_exchange_weak(volatile atomic&lt;T&gt;*,
                                    typename atomic&lt;T&gt;::value_type*,
                                    typename atomic&lt;T&gt;::value_type) noexcept;
template&lt;class T&gt;
  bool atomic_compare_exchange_strong(volatile atomic&lt;T&gt;*,
                                      typename atomic&lt;T&gt;::value_type*,
                                      typename atomic&lt;T&gt;::value_type) noexcept;
template&lt;class T&gt;
  bool atomic_compare_exchange_weak_explicit(volatile atomic&lt;T&gt;*,
                                             typename atomic&lt;T&gt;::value_type*,
                                             typename atomic&lt;T&gt;::value_type,
                                             memory_order, memory_order) noexcept;    
template&lt;class T&gt;
  bool atomic_compare_exchange_strong_explicit(volatile atomic&lt;T&gt;*,
                                               typename atomic&lt;T&gt;::value_type*,
                                               typename atomic&lt;T&gt;::value_type,
                                               memory_order, memory_order) noexcept;  
template&lt;class T&gt;
  T atomic_fetch_<i>key</i>(volatile atomic&lt;T&gt;*, typename atomic&lt;T&gt;::difference_type) noexcept;  
template&lt;class T&gt;
  T atomic_fetch_<i>key</i>_explicit(volatile atomic&lt;T&gt;*, typename atomic&lt;T&gt;::difference_type,
                              memory_order) noexcept;  
template&lt;class T&gt;
  T atomic_fetch_<i>key</i>(volatile atomic&lt;T&gt;*, typename atomic&lt;T&gt;::value_type) noexcept;  
template&lt;class T&gt;
  T atomic_fetch_<i>key</i>_explicit(volatile atomic&lt;T&gt;*, typename atomic&lt;T&gt;::value_type,
                              memory_order) noexcept;  
template&lt;class T&gt;
  void atomic_wait(const volatile atomic&lt;T&gt;*, typename atomic&lt;T&gt;::value_type);
template&lt;class T&gt;
  void atomic_wait_explicit(const volatile atomic&lt;T&gt;*, typename atomic&lt;T&gt;::value_type,
                            memory_order);
template&lt;class T&gt;
  void atomic_notify_one(volatile atomic&lt;T&gt;*);
template&lt;class T&gt;
  void atomic_notify_all(volatile atomic&lt;T&gt;*);</ins>
</pre>
</blockquote>

</blockquote>
</li>

</ol>




</body>
</html>
