<!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=utf-8">
<title>P0943R0: Support C atomics in C++</title>
<style type="text/css">
html { line-height: 135%; }
ins { background-color: #DFD; }
del { background-color: #FDD; }
</style>
</head>
<body>
<table>
        <tr>
                <th>Doc. No.:</th>
                <td>WG21/P0943R0</td>
        </tr>
        <tr>
                <th>Date:</th>
                <td>2018-02-11</td>
        </tr>
        <tr>
                <th>Reply-to:</th>
                <td>Hans-J. Boehm</td>
        </tr>
        <tr>
                <th>Email:</th>
                <td><a href="mailto:hboehm@google.com">hboehm@google.com</a></td>
        </tr>
        <tr>
                <th>Authors:</th>
                <td>Hans-J. Boehm</td>
        </tr>
        <tr>
                <th>Audience:</th>
                <td>SG1 (quick check?), LEWG (namespace issues)</td>
        </tr>
</table>

<h1>P0943R0: Support C atomics in C++</h1>
<p>
As we previously suggested in
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0063r0.html">P0063R0</a>,
it would be nice to have a real interoperability story for C atomics and C++ atomics.
In the interest of time, and since it appeared to be less essential and more controversial
than the rest of that proposal, this suggestion was not pursued further in later revisions
of that paper. Nonetheless, it remains a gaping hole in the interoperability story between
C and C++. The solution proposed here is based on one that has been used by Android
for several years.
<h2>The Problem</h2>
<p>
It is desirable to make C language header files directly usable by C++ code.
It is increasingly common for such header files to include declarations that
rely on atomics.
<p>
For example, a header may wish to declare a function that provides saturating
("clamped") addition on atomic integers. This can easily be implemented in the
common subset of C and C++, except that we have no convenient and portable way to
include the definition of names such as <code>atomic_int</code>, that are
defined in <code>&lt;atomic&gt;</code> in C++ and
in <code>&lt;stdatomic.h&gt;</code> in C.
<p>
The best we can currently
do in portable code is to use an explicit preprocessor test followed by conditional
inclusion of either <code>&lt;atomic&gt;</code> or <code>&lt;stdatomic.h&gt;</code>.
In the former case, we then have
to add <code>using</code> declarations to inject the required types and functions
into the global namespace. Thus we end up with something like
<blockquote>
<p>
<pre><code>
#ifdef __cplusplus
  #include &lt;atomic&gt;
  using std::atomic_int;
  using std::memory_order;
  using std::memory_order_acquire;
  ...
#else /* not __cplusplus */
  #include &lt;stdatomic.h&gt;
#endif /* __cplusplus */
...
int saturated_fetch_add(atomic_int *loc, int value, memory_order order);
</code></pre>
</blockquote>
<p>
This approach relies on
the currently implicit assumption or wish that the representation of C and C++
atomics are compatible.
<p>
Although certainly possible, this is very clumsy compared to the level of
interoperability we normally provide; for other language features we commonly
provide a C header file that can be included from C++, and provides
the necessary declarations. Here we propose to do the same for atomics.
<p>
The story here is somewhat confused by the fact that most of
the other <code>.h</code> compatibility headers currently only appear in
the deprecated features section under D.5 C standard library headers [depr.c.headers].
A recent paper,
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0619r2.html">P0619</a>
proposes to undeprecate them. We strongly agree with this paper that the
current deprecation of these headers does not reflect reality.
Many of them are widely used and heavily relied upon.
This proposal assumes that at least some of those headers will be preserved.

<h2>History</h2>
<p>
C and C++ atomics were originally designed together. The original design ensured that the
non-generic pieces of the C++ atomics library were usable as a C library. This interoperability
story became less clear as a result of several later decisions:
<ul>
<li> WG14 adopted, in addition to the non-generic parts of the C++ library, a
more generic facility, relying on the <code>_Atomic</code> type qualifier,
and the <code>_Atomic(T)</code> type specifier. This happened late enough in the
C++11 standardization cycle that there wasn't much of an opportunity for C++
adjustments.
<li> C++ has never defined what it means to include <code>stdatomic.h</code> in a
C++ program.
</ul>
<p>
Shortly before finalizing C++11, we briefly discussed accommodating <code>_Atomic</code>
roughly as described here.

<h2>Proposal</h2>
<p>
We propose to add a header <code>stdatomic.h</code> to the C++ standard. This would
mirror the identically named C header, and provide comparable functionality.
However, instead of defining it in terms of the C header, we propose that it have
the following effects:
<ol>
<li> Include the <code>&lt;atomic&gt;</code> header.
<li> Define a macro <code>_Atomic(T)</code> as <code>std::atomic&lt;T&gt;</code>.
<li> Promote all <code>atomic_</code>... and <code>memory_order</code>...
identifiers introduced by the <code>&lt;atomic&gt;</code> header into the global name space.
</ol>
<p>
Although this provides functionality very similar to the C header, it is unlikely
that it will be exactly the same. As usual, it is the responsibility of the author
of a C and C++ shared header to ensure that the code is correct in both languages.
<p>
This proposal makes no effort to support the C <code>_Atomic</code> type qualifier,
as opposed to the type <i>specifier</i> (which is spelled with parentheses).
This is intentional; accommodating the qualifier would be a major language
change, particularly since it is the only type qualifier that can affect
alignment.
<p>
We believe this is the minimum required to conveniently use atomics in shared
headers.

<h2>Implementation compatibility</h2>
<p>
This proposal reflects current practice in Android since the Android Lollipop release in 2014.
(See <a href="https://android.googlesource.com/platform/bionic/+/lollipop-release/libc/include/stdatomic.h">
https://android.googlesource.com/platform/bionic/+/lollipop-release/libc/include/stdatomic.h</a>.
That uses a single include file shared between C and C++, which may not be the optimal
implementation strategy.)
<p>
As far as we can tell, it should be easy to support in other implementations.
We do rely on the fact that atomics implementations for C and C++ use
compatible representation, ordering, and locking conventions.
Preliminary experiments with gcc-4.9 suggest that C and C++ atomics generate
identical code on x86-64, and code that only gratuitously differs in alignment
constraints on ARMv7. In both cases, simple code with mixed atomic operations
on objects of different sizes ran correctly.
<p>
We were not yet able to reproduce this experiment with other compilers, in
part because support for C atomics on older, default installed, compiler
versions is often still lacking. We hope to test with newer compilers soon.
<p>
There is no reason to implement C and C++ atomics differently.
Implementing ordering constraints in incompatible ways is already greatly
undesirable, in that mixed language programs with <code>memory_order</code>
annotations would no longer be sequentially consistent. Using incompatible
locking schemes for large atomics would generally double the amount of space
required for the lock table, and complicate ABI conventions, with no
benefit.
<p>
Thus we expect that in most cases, the implementation effort here consists
of adding a simple header file. Implementations that also support C atomics
should already satisfy the remaining constraints. And those constraints
are vacuous for implementations that don't.

<h2>Should there be a <code>&lt;cstdatomic&gt;</code>?</h2>
<p>
We do not believe there is a strong need to introduce a <code>&lt;cstdatomic&gt;</code>
that only introduces names into the <code>std::</code> namespace. The
justification for <code>&lt;stdatomic.h&gt;</code> is entirely to support
headers shared between C and C++, not to import a C facility into C++.
A shared header will not be able to take advantage of names introduced into the
<code>std::</code> namespace.
<p>
There is an argument that <code>&lt;cstdatomic&gt;</code> should be provided
anyway for uniformity. It's not clear that this outweighs the cost of introducing
a header that we expect to get essentially no use.

<h2>Wording</h2>
<p>
Placement and details of the wording are heavily dependent on the outcome of the
P0619 discussion. We expect something along the following lines:
<blockquote>
<ins>The header <code>&lt;stdatomic.h&gt;</code> behaves as if it consisted of:</ins>
<pre><code><ins>
#include &lt;atomic&gt;
#define _Atomic(T) std::atomic&lt;T&gt;
using std::memory_order;
using std::atomic_<i>X</i>;  // Repeated for all <i>X</i>
using std::memory_order_<i>Y</i>;  // Repeated for all <i>Y</i>
</ins></code></pre>
<p>
<ins>where the last two <code>using</code> directives are repeated for every
identifier with names starting with <code>atomic_</code> or <code>memory_order_</code> 
introduced by Clause 32 [atomics].</ins>
<p>
<ins>[Note: Implementations should ensure that C and C++ representations of atomic
objects are compatible, so that the same object can be safely accessed as both
an <code>_Atomic(T)</code> from C code and <code>atomic&lt;T&gt;</code> from C++ code. The
representations should be the same, and the mechanisms used to ensure atomicity
and memory ordering should be compatible. --end note]</ins>
</blockquote>
<p>
Note that the above is essentially a verbatim reflection of the part of the Android
<code>&lt;stdatomic.h&gt;</code> header that is used when compiling C++.
</body>
</html>
