C and C++ Liaison: Compatibility for Atomics

ISO/IEC JTC1 SC22 WG14 N1508 - 2010-08-22
ISO/IEC JTC1 SC22 WG21 N3137 = 10-0127 - 2010-08-22

Lawrence Crowl, crowl@google.com, Lawrence@Crowl.org

Introduction

The draft of C1X includes a facility for atomics. The primary change in this this facility in the latest draft N1494 is incorporation of a new atomics proposal for a productive syntax for declaring atomic types and operators for atomic types. C++0x FCD national body comment CA 23 (and more generally US 1) requests compatibility between C and C++ with respect to atomics.

Issues

The concurrency subgroup of WG21 went through the compatibility issues and in some cases chose a course of action. When we chose a course of action, it was without objection.

Declaration Syntax

The central compatibility issue is a productive syntax for declaring atomic types and objects that is the same in both C and C++.

C++ shall provide an _Atomic(T) macro.

The definition would be as follows.

#define _Atomic(T) atomic<T>

to enable compatible declaration of atomic types and objects.

_Atomic(int) var;

C++ shall not provide the lower-case atomic macro.

An alternative was a lower case macro.

#define atomic(T) atomic<T>

enabling both declarations

atomic(int) var;
atomic<int> alt;

However, the committee felt that such dual use of atomic would be confusing at best.

C++ shall not provide an _Atomic type qualifier.

The current C draft provides support for use of _Atomic as a type qualifier. Such a use would require considerable change to the C++ standard at a late date and introduce potential semantic difficulties.

The committee discussed recommending that C not adopt the qualifier, but the conversation ended without a conclusion.

Free Function/Macro Parameters

The free functions/macros currently require taking the address of the atomic object.

int answer = atomic_fetch_add( &var, 3 );

C++ shall not change the atomic object parameters to lvalues.

The consensus was that it was too late in the process for an essentially unnecessary change. (Such a change would also require different parameter conventions for C functions and C macros.)

Atomic Type Hierarchy

The C++ FCD specifies atomic_int as a base class of atomic<int> to enable compatiblity with C parameters. For example,

extern "C" void some_C_function( atomic_int* arg );
atomic<int> var;
.... { .... some_C_function( &var ); .... } ....

However, with a productive C syntax,

typedef _Atomic(int) atomic_int;

would result in a diffent type from the existing C++ atomic_int.

C++ shall removed the named types as bases for the template specializations.

This approach ensures type compatibility.

Simple Type Names

With the introduction of a productive C syntax, the plethora of simple type names (either struct or typedef) is no longer necessary.

C++ shall remove the simple type names.

The feeling was that the standard would be clearer without the additional names.

Non-Integral Operations

The current C draft includes support for arithmetic operations on floating-point types. The C++ draft does not.

C++ shall not support floating-point arithmetic operations.

The C++ committee does not know of any compelling use cases for atomic floats. The C++ committee believes the C standard under-specifies the effect of atomic floating arithmetic operations in the presence of floating-point traps. Therefore, it is prudent and conservative to not support atomic floating-point arithmetic operations in the upcoming versions of the standard.

The C++ committee recommends that the C committee not support floating-point operations.

In keeping with the discussion above.

Headers

The original C++ atomics proposal included a header <stdatomic.h>. However, the header was later changed to <atomic> to remove an potentially interference with the C standard. The C standard has now adopted the <stdatomic.h> header and the C++ standard must accept it.

C++ shall define a <stdatomic.h> header that provides the atomic types and functions in the global namespace.

C++ shall provide the _Atomic macro in <stdatomic.h> but not in <atomic>

Open Issue

It is an open issue whether C++ shall provide the atomic type member functions in <stdatomic.h>.

Bitfields

The C draft includes support for atomic bitfields.

C++ shall not provide atomic bitfields.

The C++ definitional template-based approach is incompatible with atomic bitfields.

The C++ committee knows of no use cases requiring atomic bitfields. Conservatively, then, the languages should not require them.

The C++ committee recommends that the C committee not support atomic bitfields.

As per the reasons above.

Assignment Operator

In C, assignment is used for both initialization and value replacement. On the other hand, C++ carefully distinguishes between initialization (construction) and value replacement (copy assignment). For implementations of atomics that require a lock internal to the object, this distinction is critical. IBM confirms that zOS requires such an implementation.

Open Issue

Possible resolutions to the above problem are still under discussion.

Access to Members of Atomics

C permits access to memberf of an atomic stuct or union. C++ does not, one must copy the whole value into and out of the atomic object. This approach avoids the implementation costs of hierarchical locking.

Open Issue

Possible resolutions to the above problem are still under discussion.