<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
   "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=US-ASCII">
<title>Adjusting C++ Atomics for C Compatibility</title>
</head>

<body>
<h1>Adjusting C++ Atomics for C Compatibility</h1>

<p>
ISO/IEC JTC1 SC22 WG21 N3193 = 10-0183 - 2010-11-12
</p>

<p>
Lawrence Crowl, crowl@google.com, Lawrence@Crowl.org
</p>

<p>
This paper revises
ISO/IEC JTC1 SC22 WG21 N3164 = 10-0154 - 2010-10-14.
</p>

<p>
<a href="#Introduction">Introduction</a><br>
<a href="#Wording">Wording</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#atomics.syn">29.2 Header <code>&lt;atomic&gt;</code> synopsis [atomics.syn]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#atomics.types">29.5 Atomic Types [atomics.types]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#atomics.types.integral">29.5.1 Integral Types [atomics.types.integral]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#atomics.types.address">29.5.2 Address Type [atomics.types.address]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#atomics.types.generic">29.5.3 Generic Type [atomics.types.generic]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#atomics.types.operations">29.6 Operations on Atomic Types [atomics.types.operations]</a><br>
</p>

<h2><a name="Introduction">Introduction</a></h2>

<p>
The draft of
<a href="http://www.open-std.org/JTC1/SC22/WG14/">C1X</a>
includes a facility for atomics.
The primary change in this facility in the draft
<a href="http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1494.pdf">N1494</a>
is incorporation of a
<a href="http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1485.pdf">new
atomics proposal</a>
for a <em>productive</em> syntax
for declaring atomic types and operators for atomic types.
(The latest C1X draft is
<a href="http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1516.pdf">N1516</a>.)
C++0x FCD national body comments CA 23, CH 22, GB 128 and more generally US 1
request compatibility between C and C++ with respect to atomics.
</p>

<p>
This paper provides normative wording changes
to reflect the choices in 
<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2010/n3137.html">
N3137 C and C++ Liaison: Compatibility for Atomics</a>.
</p>

<p>
In summary, the changes are:
</p>

<ul>

<li>
Changed the definitions of named <code>atomic_</code>.... types
to be either the corresponding specialization or a base class thereof,
except for <code>atomic_flag</code> and <code>atomic_address</code>.
The <code>atomic_flag</code> type is special,
and is not part of the normal productive atomic syntax.
It remains.
The <code>atomic_address</code> type is unsafe.
It and its corresponding <code>ATOMIC_ADDRESS_LOCK_FREE</code> macro
are removed.
</li>

<li>
Remove the definional base-class relationship
between <code>atomic_</code>....  named types
and the corresponding specializations
of the <code>atomic</code> template class.
The base-class relationship is now implementation-dependent.
This change ensures compatibility with C.
Some member functions and operators,
that were formerly inherited from the base class,
must be hoisted from the named types to the specializations.
</li>

<li>
Change the <code>atomic_</code>.... freestanding functions to templates,
as they must now cover arbitrary atomic types
rather than just the named types.
Some specializations are required.
</li>

<li>
Correct some of the wording
around <code>ATOMIC_VAR_INIT</code> and <code>atomic_init</code>.
</li>

</ul>

<p>
Other issues addressed by this paper are as follows:
</p>
<table border=1>
<tr><td>GB 132</td>
<td>addressed by refactoring of definitions</td></tr>
<tr><td>GB 133, US 161, US 163, US 164</td>
<td>made moot by the removal of <code>atomic_address</code></td></tr>
</table>


<h2><a name="Wording">Wording</a></h2>

<p>
This wording is relative to
<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2010/n3126.pdf">
N3126 Working Draft, Standard for Programming Language C++</a>.
</p>

<h3><a name="atomics.syn">29.2 Header <code>&lt;atomic&gt;</code> synopsis [atomics.syn]</a></h3>

<p>
Remove the <code>ATOMIC_ADDRESS_LOCK_FREE</code> macro.
</p>

<p>
Move the <code>ATOMIC_VAR_INIT</code> macro declaration
to its proper order with respect to the sections.
</p>

<p>
Move the <code>atomic_flag</code> type and function declarations
to their proper order with respect to the sections.
</p>

<p>
Remove the declaration block for
<code>atomic_bool</code> and associated functions.
</p>

<p>
Remove the declaration block for
<code>atomic_<var>itype</var></code> and associated functions.
</p>

<p>
Remove the declaration block for
<code>atomic_address</code> and associated functions.
</p>

<p>
Modify the section number for the generic type definitions to 29.5.
</p>

<p>
For section 29.6,
add generic free functions as follows.
The functions mirror C type-generic macros.
</p>

<blockquote>
<p>
Within the following declarations,
<code><var>atomic-type</var></code> is
either <code>atomic&lt;Type&gt;</code>
or a named base class for <code>Type</code>
from table AA or implied from table BB.
</p>
<pre><code>
<ins>template &lt;typename Type&gt;
bool atomic_is_lock_free(const volatile <var>atomic-type</var>*);
template &lt;typename Type&gt;
bool atomic_is_lock_free(const <var>atomic-type</var>*);
template &lt;typename Type&gt;
void atomic_init(volatile <var>atomic-type</var>*, Type);
template &lt;typename Type&gt;
void atomic_init(<var>atomic-type</var>*, Type);
template &lt;typename Type&gt;
void atomic_store(volatile <var>atomic-type</var>*, Type);
template &lt;typename Type&gt;
void atomic_store(<var>atomic-type</var>*, Type);
template &lt;typename Type&gt;
void atomic_store_explicit(volatile <var>atomic-type</var>*, Type, memory_order);
template &lt;typename Type&gt;
void atomic_store_explicit(<var>atomic-type</var>*, Type, memory_order);
template &lt;typename Type&gt;
Type atomic_load(const volatile <var>atomic-type</var>*);
template &lt;typename Type&gt;
Type atomic_load(const <var>atomic-type</var>*);
template &lt;typename Type&gt;
Type atomic_load_explicit(const volatile <var>atomic-type</var>*, memory_order);
template &lt;typename Type&gt;
Type atomic_load_explicit(const <var>atomic-type</var>*, memory_order);
template &lt;typename Type&gt;
Type atomic_exchange(volatile <var>atomic-type</var>*, Type);
template &lt;typename Type&gt;
Type atomic_exchange(<var>atomic-type</var>*, Type);
template &lt;typename Type&gt;
Type atomic_exchange_explicit(volatile <var>atomic-type</var>*, Type, memory_order);
template &lt;typename Type&gt;
Type atomic_exchange_explicit(<var>atomic-type</var>*, Type, memory_order);
template &lt;typename Type&gt;
bool atomic_compare_exchange_weak(volatile <var>atomic-type</var>*, Type*, Type);
template &lt;typename Type&gt;
bool atomic_compare_exchange_weak(<var>atomic-type</var>*, Type*, Type);
template &lt;typename Type&gt;
bool atomic_compare_exchange_strong(volatile <var>atomic-type</var>*, Type*, Type);
template &lt;typename Type&gt;
bool atomic_compare_exchange_strong(<var>atomic-type</var>*, Type*, Type);
template &lt;typename Type&gt;
bool atomic_compare_exchange_weak_explicit(volatile <var>atomic-type</var>*, Type*,
                                           Type, memory_order, memory_order);
template &lt;typename Type&gt;
bool atomic_compare_exchange_weak_explicit(<var>atomic-type</var>*, Type*,
                                           Type, memory_order, memory_order);
template &lt;typename Type&gt;
bool atomic_compare_exchange_strong_explicit(volatile <var>atomic-type</var>*, Type*,
                                             Type, memory_order, memory_order);
template &lt;typename Type&gt;
bool atomic_compare_exchange_strong_explicit(<var>atomic-type</var>*, Type*,
                                             Type, memory_order, memory_order);</ins>
</code></pre>
</blockquote>

<p>
For section 29.6,
add generic free functions as follows.
</p>

<blockquote>
<p>
Each of the following declarations has no implementation.
In each declaration,
<code><var>atomic-type</var></code> is
either <code>atomic&lt;Type&gt;</code>
or a named base class for <code>Type</code>
from table AA or implied from table BB.
</p>
<pre><code>
<ins>template &lt;typename Type&gt;
Type atomic_fetch_add(volatile <var>atomic-type</var>*, Type);
template &lt;typename Type&gt;
Type atomic_fetch_add(<var>atomic-type</var>*, Type);
template &lt;typename Type&gt;
Type atomic_fetch_add_explicit(volatile <var>atomic-type</var>*, Type, memory_order);
template &lt;typename Type&gt;
Type atomic_fetch_add_explicit(<var>atomic-type</var>*, Type, memory_order);
template &lt;typename Type&gt;
Type atomic_fetch_sub(volatile <var>atomic-type</var>*, Type);
template &lt;typename Type&gt;
Type atomic_fetch_sub(<var>atomic-type</var>*, Type);
template &lt;typename Type&gt;
Type atomic_fetch_sub_explicit(volatile <var>atomic-type</var>*, Type, memory_order);
template &lt;typename Type&gt;
Type atomic_fetch_sub_explicit(<var>atomic-type</var>*, Type, memory_order);
template &lt;typename Type&gt;
Type atomic_fetch_and(volatile <var>atomic-type</var>*, Type);
template &lt;typename Type&gt;
Type atomic_fetch_and(<var>atomic-type</var>*, Type);
template &lt;typename Type&gt;
Type atomic_fetch_and_explicit(volatile <var>atomic-type</var>*, Type, memory_order);
template &lt;typename Type&gt;
Type atomic_fetch_and_explicit(<var>atomic-type</var>*, Type, memory_order);
template &lt;typename Type&gt;
Type atomic_fetch_or(volatile <var>atomic-type</var>*, Type);
template &lt;typename Type&gt;
Type atomic_fetch_or(volatile <var>atomic-type</var>*, Type);
template &lt;typename Type&gt;
Type atomic_fetch_or_explicit(volatile <var>atomic-type</var>*, Type, memory_order);
template &lt;typename Type&gt;
Type atomic_fetch_or_explicit(<var>atomic-type</var>*, Type, memory_order);
template &lt;typename Type&gt;
Type atomic_fetch_xor(volatile <var>atomic-type</var>*, Type);
template &lt;typename Type&gt;
Type atomic_fetch_xor(<var>atomic-type</var>*, Type);
template &lt;typename Type&gt;
Type atomic_fetch_xor_explicit(volatile <var>atomic-type</var>*, Type, memory_order);
template &lt;typename Type&gt;
Type atomic_fetch_xor_explicit(<var>atomic-type</var>*, Type, memory_order);</ins>
</code></pre></blockquote>

<p>
For section 29.6,
add the following integral specializations.
</p>

<blockquote>
<p>
In each of the following declarations,
<code><var>integral</var></code> is an integral type,
<code><var>atomic-integral</var></code> is
either <code>atomic&lt;<var>integral</var>&gt;</code>
or a named base class for <code><var>integral</var></code>
from table AA or implied from table BB.
</p>

<pre><code>
<ins>template &lt;&gt;
<var>integral</var> atomic_fetch_add(volatile <var>atomic-integral</var>*, <var>integral</var>);
template &lt;&gt;
<var>integral</var> atomic_fetch_add(<var>atomic-integral</var>*, <var>integral</var>);
template &lt;&gt;
<var>integral</var> atomic_fetch_add_explicit(volatile <var>atomic-integral</var>*, <var>integral</var>,
                                   memory_order);
template &lt;&gt;
<var>integral</var> atomic_fetch_add_explicit(<var>atomic-integral</var>*, <var>integral</var>,
                                   memory_order);
template &lt;&gt;
<var>integral</var> atomic_fetch_sub(volatile <var>atomic-integral</var>*, <var>integral</var>);
template &lt;&gt;
<var>integral</var> atomic_fetch_sub(<var>atomic-integral</var>*, <var>integral</var>);
template &lt;&gt;
<var>integral</var> atomic_fetch_sub_explicit(volatile <var>atomic-integral</var>*, <var>integral</var>,
                                   memory_order);
template &lt;&gt;
<var>integral</var> atomic_fetch_sub_explicit(<var>atomic-integral</var>*, <var>integral</var>,
                                   memory_order);
template &lt;&gt;
<var>integral</var> atomic_fetch_and(volatile <var>atomic-integral</var>*, <var>integral</var>);
template &lt;&gt;
<var>integral</var> atomic_fetch_and(<var>atomic-integral</var>*, <var>integral</var>);
template &lt;&gt;
<var>integral</var> atomic_fetch_and_explicit(volatile <var>atomic-integral</var>*, <var>integral</var>,
                                   memory_order);
template &lt;&gt;
<var>integral</var> atomic_fetch_and_explicit(<var>atomic-integral</var>*, <var>integral</var>,
                                   memory_order);
template &lt;&gt;
<var>integral</var> atomic_fetch_or(volatile <var>atomic-integral</var>*, <var>integral</var>);
template &lt;&gt;
<var>integral</var> atomic_fetch_or(volatile <var>atomic-integral</var>*, <var>integral</var>);
template &lt;&gt;
<var>integral</var> atomic_fetch_or_explicit(volatile <var>atomic-integral</var>*, <var>integral</var>,
                                   memory_order);
template &lt;&gt;
<var>integral</var> atomic_fetch_or_explicit(<var>atomic-integral</var>*, <var>integral</var>,
                                   memory_order);
template &lt;&gt;
<var>integral</var> atomic_fetch_xor(volatile <var>atomic-integral</var>*, <var>integral</var>);
template &lt;&gt;
<var>integral</var> atomic_fetch_xor(<var>atomic-integral</var>*, <var>integral</var>);
template &lt;&gt;
<var>integral</var> atomic_fetch_xor_explicit(volatile <var>atomic-integral</var>*, <var>integral</var>,
                                   memory_order);
template &lt;&gt;
<var>integral</var> atomic_fetch_xor_explicit(<var>atomic-integral</var>*, <var>integral</var>,
                                   memory_order);</ins>
</code></pre></blockquote>

<p>
For section 29.6,
add generic free functions as follows.
These functions correspond to
the <code>atomic</code> class template partial specialization for pointers.
</p>

<blockquote><pre><code>
<ins>template &lt;typename Type&gt;
Type atomic_fetch_add(volatile atomic&lt;Type*&gt;*, ptrdiff_t);
template &lt;typename Type&gt;
Type atomic_fetch_add(atomic&lt;Type*&gt;*, ptrdiff_t);
template &lt;typename Type&gt;
Type atomic_fetch_add_explicit(volatile atomic&lt;Type*&gt;*, ptrdiff_t,
                               memory_order);
template &lt;typename Type&gt;
Type atomic_fetch_add_explicit(atomic&lt;Type*&gt;*, ptrdiff_t,
                               memory_order);
template &lt;typename Type&gt;
Type atomic_fetch_sub(volatile atomic&lt;Type*&gt;*, ptrdiff_t);
template &lt;typename Type&gt;
Type atomic_fetch_sub(atomic&lt;Type*&gt;*, ptrdiff_t);
template &lt;typename Type&gt;
Type atomic_fetch_sub_explicit(volatile atomic&lt;Type*&gt;*, ptrdiff_t,
                               memory_order);
template &lt;typename Type&gt;
Type atomic_fetch_sub_explicit(atomic&lt;Type*&gt;*, ptrdiff_t,
                               memory_order);</ins>
</code></pre></blockquote>


<h3><a name="atomics.types">29.5 Atomic Types [atomics.types]</a></h3>

<p>
This section has the bulk of changes,
removing the named types in favor of only providing the productive type syntax.
The approach is to remove the sections on integral types and address types,
and turn the subsection on generic types to the section on types.
</p>

<h3><a name="atomics.types.integral">29.5.1 Integral Types [atomics.types.integral]</a></h3>

<p>
Remove this section.
</p>

<h3><a name="atomics.types.address">29.5.2 Address Type [atomics.types.address]</a></h3>

<p>
Remove this section.
</p>

<h3><a name="atomics.types.generic">29.5.3 Generic Type [atomics.types.generic]</a></h3>

<p>
Rename this subsection to 29.5 Atomic Types [atomics.types].
</p>

<p>
Edit the synopsis for the integral type specializations as follows.
</p>

<blockquote><pre><code>
template &lt;&gt; struct atomic&lt;<var>integral</var>&gt; <del>: atomic_<var>itype</var></del> {

<ins>    bool is_lock_free() const volatile;
    bool is_lock_free() const;
    void store(<var>integral</var>, memory_order = memory_order_seq_cst) volatile;
    void store(<var>integral</var>, memory_order = memory_order_seq_cst);
    <var>integral</var> load(memory_order = memory_order_seq_cst) const volatile;
    <var>integral</var> load(memory_order = memory_order_seq_cst) const;</ins>
    operator <var>integral</var>() const volatile;
    operator <var>integral</var>() const;
<ins>    <var>integral</var> exchange(<var>integral</var>,
                      memory_order = memory_order_seq_cst) volatile;
    <var>integral</var> exchange(<var>integral</var>,
                      memory_order = memory_order_seq_cst);
    bool compare_exchange_weak(<var>integral</var>&amp;, <var>integral</var>,
                               memory_order, memory_order) volatile;
    bool compare_exchange_weak(<var>integral</var>&amp;, <var>integral</var>,
                               memory_order, memory_order);
    bool compare_exchange_strong(<var>integral</var>&amp;, <var>integral</var>,
                                 memory_order, memory_order) volatile;
    bool compare_exchange_strong(<var>integral</var>&amp;, <var>integral</var>,
                                 memory_order, memory_order);
    bool compare_exchange_weak(<var>integral</var>&amp;, <var>integral</var>,
                               memory_order = memory_order_seq_cst) volatile;
    bool compare_exchange_weak(<var>integral</var>&amp;, <var>integral</var>,
                               memory_order = memory_order_seq_cst);
    bool compare_exchange_strong(<var>integral</var>&amp;, <var>integral</var>,
                                 memory_order = memory_order_seq_cst) volatile;
    bool compare_exchange_strong(<var>integral</var>&amp;, <var>integral</var>,
                                 memory_order = memory_order_seq_cst);
    <var>integral</var> fetch_add(<var>integral</var>,
                       memory_order = memory_order_seq_cst) volatile;
    <var>integral</var> fetch_add(<var>integral</var>,
                       memory_order = memory_order_seq_cst);
    <var>integral</var> fetch_sub(<var>integral</var>,
                       memory_order = memory_order_seq_cst) volatile;
    <var>integral</var> fetch_sub(<var>integral</var>,
                       memory_order = memory_order_seq_cst);
    <var>integral</var> fetch_and(<var>integral</var>,
                       memory_order = memory_order_seq_cst) volatile;
    <var>integral</var> fetch_and(<var>integral</var>,
                       memory_order = memory_order_seq_cst);
    <var>integral</var> fetch_or(<var>integral</var>,
                       memory_order = memory_order_seq_cst) volatile;
    <var>integral</var> fetch_or(<var>integral</var>,
                       memory_order = memory_order_seq_cst);
    <var>integral</var> fetch_xor(<var>integral</var>,
                       memory_order = memory_order_seq_cst) volatile;
    <var>integral</var> fetch_xor(<var>integral</var>,
                       memory_order = memory_order_seq_cst);</ins>

    atomic() = default;
    constexpr atomic(<var>integral</var>);
    atomic(const atomic&amp;) = delete;
    atomic&amp; operator=(const atomic&amp;) = delete;
    atomic&amp; operator=(const atomic&amp;) volatile = delete;
    <var>integral</var> operator=(<var>integral</var>) volatile;
    <var>integral</var> operator=(<var>integral</var>);

<ins>    <var>integral</var> operator++(int) volatile;
    <var>integral</var> operator++(int);
    <var>integral</var> operator--(int) volatile;
    <var>integral</var> operator--(int);
    <var>integral</var> operator++() volatile;
    <var>integral</var> operator++();
    <var>integral</var> operator--() volatile;
    <var>integral</var> operator--();
    <var>integral</var> operator+=(<var>integral</var>) volatile;
    <var>integral</var> operator+=(<var>integral</var>);
    <var>integral</var> operator-=(<var>integral</var>) volatile;
    <var>integral</var> operator-=(<var>integral</var>);
    <var>integral</var> operator&amp;=(<var>integral</var>) volatile;
    <var>integral</var> operator&amp;=(<var>integral</var>);
    <var>integral</var> operator|=(<var>integral</var>) volatile;
    <var>integral</var> operator|=(<var>integral</var>);
    <var>integral</var> operator^=(<var>integral</var>) volatile;
    <var>integral</var> operator^=(<var>integral</var>);</ins>
};
</code></pre></blockquote>

<p>
Edit the synopsis for the pointer type specializations as follows.
</p>

<blockquote><pre><code>
template &lt;class T&gt; struct atomic&lt;T*&gt; <del>: atomic_address</del> {

<ins>    bool is_lock_free() const volatile;
    bool is_lock_free() const;</ins>
    void store(T*, memory_order = memory_order_seq_cst) volatile;
    void store(T*, memory_order = memory_order_seq_cst);
    T* load(memory_order = memory_order_seq_cst) const volatile;
    T* load(memory_order = memory_order_seq_cst) const;
    operator T*() const volatile;
    operator T*() const;
    T* exchange(T*, memory_order = memory_order_seq_cst) volatile;
    T* exchange(T*, memory_order = memory_order_seq_cst);
    bool compare_exchange_weak(T*&amp;, T*,
                               memory_order, memory_order) volatile;
    bool compare_exchange_weak(T*&amp;, T*,
                               memory_order, memory_order);
    bool compare_exchange_strong(T*&amp;, T*,
                                 memory_order, memory_order) volatile;
    bool compare_exchange_strong(T*&amp;, T*,
                                 memory_order, memory_order);
    bool compare_exchange_weak(T*&amp;, T*,
                               memory_order = memory_order_seq_cst) volatile;
    bool compare_exchange_weak(T*&amp;, T*,
                               memory_order = memory_order_seq_cst);
    bool compare_exchange_strong(T*&amp;, T*,
                                 memory_order = memory_order_seq_cst) volatile;
    bool compare_exchange_strong(T*&amp;, T*,
                                 memory_order = memory_order_seq_cst);
    T* fetch_add(ptrdiff_t, memory_order = memory_order_seq_cst) volatile;
    T* fetch_add(ptrdiff_t, memory_order = memory_order_seq_cst);
    T* fetch_sub(ptrdiff_t, memory_order = memory_order_seq_cst) volatile;
    T* fetch_sub(ptrdiff_t, memory_order = memory_order_seq_cst);
    
    atomic() = default;
    constexpr atomic(T*);
    atomic(const atomic&amp;) = delete;
    atomic&amp; operator=(const atomic&amp;) = delete;
    atomic&amp; operator=(const atomic&amp;) volatile = delete;

    T* operator=(T*) volatile;
    T* operator=(T*);
    T* operator++(int) volatile;
    T* operator++(int);
    T* operator--(int) volatile;
    T* operator--(int);
    T* operator++() volatile;
    T* operator++();
    T* operator--() volatile;
    T* operator--();
    T* operator+=(ptrdiff_t) volatile;
    T* operator+=(ptrdiff_t);
    T* operator-=(ptrdiff_t) volatile;
    T* operator-=(ptrdiff_t);
};
</code></pre></blockquote>

<p>
After paragraph 1, add a new paragraph.
</p>

<blockquote>
<p>
The semantics of the operations on <code>atomic</code> specializations
are defined in 29.6.
</p>
</blockquote>

<p>
Edit paragraph 3 as follows.
</p>

<blockquote><p>
There are full specializations over the integral types
<ins>
(<code>char</code>,
<code>signed char</code>,
<code>unsigned char</code>,
<code>short</code>,
<code>unsigned short</code>,
<code>int</code>,
<code>unsigned int</code>,
<code>long</code>,
<code>unsigned long</code>,
<code>long long</code>,
<code>unsigned long long</code>,
<code>char16_t</code>,
<code>char32_t</code>,
<code>wchar_t</code>,
and any other types need by <code>&lt;cstdint&gt;</code> typedefs.)
</ins>
on the atomic class template.
For each integral type <var>integral</var>
<del>in the second column of Table 142 or Table 143</del>,
the specialization <code>atomic&lt;integral&gt;</code>
<del>shall be publicly derived from the corresponding atomic integral type
in the first column of the table.
In addition, the specialization <code>atomic&lt;bool&gt;</code>
shall be publicly derived from <code>atomic_bool</code>.</del>
<ins>provide additional atomic operations appropriate to integral types.</ins>
<del>These specializations
shall have trivial default constructors and trivial destructors.</del>
<ins>The atomic integral specializations
shall have standard layout.
They shall each have a trivial default constructor, and a trivial destructor.
They shall each support aggregate initialization syntax.
</ins>
</p></blockquote>

<p>
Insert a new paragraph after the one above.
</p>

<blockquote><p>
<ins>The specialization <code>atomic&lt;bool&gt;</code>
shall have standard layout.
It shall have a trivial default constructor and a trivial destructor.
It shall support aggregate initialization syntax.
</ins>
</p></blockquote>

<p>
Edit paragraph 4 as follows.
</p>

<blockquote><p>
There are pointer partial specializations
on the <code>atomic</code> class template.
<del>These specializations shall be publicly derived from atomic_address.
The unit of addition/subtraction for these specializations
shall be the size of the referenced type.</del>
These specializations
shall have trivial default constructors and trivial destructors.
</p></blockquote>

<p>
Insert a new paragraph after the one above.
</p>

<blockquote><p>
[<i>Note:</i>
The representation of atomic specializations
need not have the same size as their corresponding argument types.
They should have the same size whenever possible,
as it eases effort required to port existing code.
&mdash;<i>end note</i>]
</p></blockquote>

<p>
After paragraph 4, add a new paragraph and tables as follows.
</p>

<blockquote>
<p>
There are named types corresponding to
the integral specializations of <code>atomic</code>,
as specified in table <var>AA</var>.
These named types are either typedefs to the corresponding specialization,
or base classes of those specializations.
If they are bases classes,
those classes shall support the same member functions as their specialization.
<p>

<table border=1>
<caption>Table <var>AA</var>
&mdash; <code>atomic</code> integral typedefs</caption>
<thead>
<tr><th>Named Type</th><th>Integral Argument Type</th></tr>
</thead>
<tbody>
<tr><td>atomic_char</td><td>char</td></tr>
<tr><td>atomic_schar</td><td>signed char</td></tr>
<tr><td>atomic_uchar</td><td>unsigned char</td></tr>
<tr><td>atomic_short</td><td>short</td></tr>
<tr><td>atomic_ushort</td><td>unsigned short</td></tr>
<tr><td>atomic_int</td><td>int</td></tr>
<tr><td>atomic_uint</td><td>unsigned int</td></tr>
<tr><td>atomic_long</td><td>long</td></tr>
<tr><td>atomic_ulong</td><td>unsigned long</td></tr>
<tr><td>atomic_llong</td><td>long long</td></tr>
<tr><td>atomic_ullong</td><td>unsigned long long</td></tr>
<tr><td>atomic_char16_t</td><td>char16_t</td></tr>
<tr><td>atomic_char32_t</td><td>char32_t</td></tr>
<tr><td>atomic_wchar_t</td><td>wchar_t</td></tr>
</tbody>
</table>

<p>
There are atomic typedefs corresponding to the typedefs
in <code>&lt;inttypes.h&gt;</code>
as specified in table <var>BB</var>.
</p>

<table border=1>
<caption>Table <var>BB</var>
&mdash; <code>atomic &lt;inttypes.h&gt;</code> typedefs</caption>
<thead>
<tr><th>Atomic Typedef</th><th><code>inttypes.h</code> Type</th></tr>
</thead>
<tbody>
<tr><td>atomic_int_least8_t</td><td>int_least8_t</td></tr>
<tr><td>atomic_uint_least8_t</td><td>uint_least8_t</td></tr>
<tr><td>atomic_int_least16_t</td><td>int_least16_t</td></tr>
<tr><td>atomic_uint_least16_t</td><td>uint_least16_t</td></tr>
<tr><td>atomic_int_least32_t</td><td>int_least32_t</td></tr>
<tr><td>atomic_uint_least32_t</td><td>uint_least32_t</td></tr>
<tr><td>atomic_int_least64_t</td><td>int_least64_t</td></tr>
<tr><td>atomic_uint_least64_t</td><td>uint_least64_t</td></tr>
<tr><td>atomic_int_fast8_t</td><td>int_fast8_t</td></tr>
<tr><td>atomic_uint_fast8_t</td><td>uint_fast8_t</td></tr>
<tr><td>atomic_int_fast16_t</td><td>int_fast16_t</td></tr>
<tr><td>atomic_uint_fast16_t</td><td>uint_fast16_t</td></tr>
<tr><td>atomic_int_fast32_t</td><td>int_fast32_t</td></tr>
<tr><td>atomic_uint_fast32_t</td><td>uint_fast32_t</td></tr>
<tr><td>atomic_int_fast64_t</td><td>int_fast64_t</td></tr>
<tr><td>atomic_uint_fast64_t</td><td>uint_fast64_t</td></tr>
<tr><td>atomic_intptr_t</td><td>intptr_t</td></tr>
<tr><td>atomic_uintptr_t</td><td>uintptr_t</td></tr>
<tr><td>atomic_size_t</td><td>size_t</td></tr>
<tr><td>atomic_ptrdiff_t</td><td>ptrdiff_t</td></tr>
<tr><td>atomic_intmax_t</td><td>intmax_t</td></tr>
<tr><td>atomic_uintmax_t</td><td>uintmax_t</td></tr>
</tbody>
</table>

</blockquote>


<h3><a name="atomics.types.operations">29.6 Operations on Atomic Types [atomics.types.operations]</a></h3>

<p>
The free functions in this section become templates or specializations thereof.
Technically, this would require adding a template name signature.
However, that change seems likely to be more confusing than helpful.
So, I have not suggested that change,
leaving it to the editor for the final decision.
</p>

<p>
Edit paragraph 1 as follows.
</p>

<blockquote><p>
There are only a few kinds of operations on atomic types,
though there are many instances on those kinds.
This section specifies each general kind.
The specific instances are defined in
<ins>29.2</ins> <del>29.5.1, 29.5.2,</del>
and <del>29.5.3</del> <ins>29.5</ins>.
</p></blockquote>

<p>
Edit paragraph 5 as follows.
</p>

<blockquote>
<p>
<i>Remarks:</i>
A macro that expands to a token sequence
suitable for <del>initializing</del> <ins>constant initialization of</ins>
an atomic variable <ins>of static storage duration</ins>
of a type that is
<del>initializion-compatible</del>
<ins>initialization-compatible</ins> with value.
<ins>
[<i>Note:</i>
This operation may need to initialize locks.
&mdash;<i>end note</i>]
</ins>
Concurrent access to the variable being initialized,
even via an atomic operation,
constitutes a data race.
[<i>Example:</i>
</p>
<blockquote><pre><code>
<del>atomic_int</del> <ins>atomic&lt;int&gt;</ins> v = ATOMIC_VAR_INIT(5);
</code></pre></blockquote>
<p>
&mdash;<i>end example</i>]
</p>
</blockquote>

<p>
Edit paragraph paragraph 7 as follows.
</p>

<blockquote>
<p>
<i>Effects:</i>
Dynamically initializes an atomic variable.
<del>Non-atomically</del>
<ins>That is, non-atomically</ins>
assigns the value desired to <code>*object</code>.
<ins>
[<i>Note:</i>
This operation may need to initialize locks.
&mdash;<i>end note</i>]
</ins>
Concurrent access from another thread,
even via an atomic operation, constitutes a data race.
</p>
</blockquote>

</body>
</html>
