Minimal suggested corrigendum for arithmetic on atomic objects


Submitter: Jens Gustedt
Submission Date: 2016-07-20
Reference Document: n2064
Version: 1.0
Date: 2016-07-20

Summary

This is a follow up on document n1955 (DR 486) that revealed several inconsistencies concerning the write up of arithmetic operations for atomic types in the standard. For the sake of brevity I will not repeat that discussion here, for the complete discussion please see the original document.

Already in the first document I proposed to act on these problems in two steps.

During discussion the committee found that the minimal corrigendum that I suggested was already too intrusive such that the committee could not easily estimate the impact on the rest of the standard. This document here is an attempt to reduce that proposal even more to make changes merely obvious.

Suggested Technical Corrigendum

5.1.2.4 p5, the text omits operators and some thread library function for the discussion as synchronization operations. change the beginning:

The library defines a number of atomic operations (7.17) and operations on mutexes (7.26.4) that are specially identified as synchronization operations.

to

The language and the library define a number of atomic operations (6.2.6.1, 6.5.16 and 7.17) operations on mutexes (7.26.4) and other library calls (7.22.3, 7.26.2.1, 7.26.5) that are specially identified as synchronization operations.

6.2.6.1 p9, for clarification replace:

Loads and stores of objects with atomic types are done with memory_order_seq_cst semantics.

by the following

Unless specified otherwise, all operations that affect objects with atomic types are done with memory_order_seq_cst semantics.

7.17.7 p1, the discussion omits operators and uses the term "kind of operations" where it should simply speak of "generic functions". Replace

There are only a few kinds of operations on atomic types, though there are many instances of those kinds. This subclause specifies each general kind.

by

In addition to the operators that are defined for atomic objects, there are a few operations that are specified as generic functions. This subclause specifies each generic function.

7.17.7.5 needs changes in p1, p3 and p5.

p1, in parts this paragraph misses pointer types as valid operands. Since only "add" and "sub" should be used for pointer types, also add a mention which operations are valid. Change:

... to an object of any atomic integer type. None of these operations is applicable to atomic_bool

to

... to an object of any atomic integer or pointer type, as long as type C is valid for the left operand of the corresponding operator op=.FOOTNOTE

FOOTNOTE: Thus none of these operations are permitted if C is _Bool, and only "add" and "sub" variants are permitted if C is a pointer type.

p3 clarify "no undefined". Even if arithmetic silently wraps around the result can be a trap representation. Address operations can be erroneous or lead to invalid values for different reasons. Also, there is no such thing as address types. Replace:

For signed integer types, arithmetic is defined to use two’s complement representation with silent wrap-around on overflow ; there are no undefined results. For address types, the result may be an undefined address, but the operations otherwise have no undefined behavior.

by

For signed integer types, arithmetic is defined to use two’s complement representation with silent wrap-around on overflow. The result and stored representation may not be a valid value for C, but the operation otherwise has no visible effect.

p5 is non-normative but factually wrong (one listed difference isn't one) and misleading (there are much more differences than listed). One solution could be to remove the entire NOTE. Otherwise replace:

The only differences are that the compound assignment operators are not guaranteed to operate atomically, and the value yielded by a compound assignment operator is the updated value of the object, whereas the value returned by the atomic_fetch and modify generic functions is the previous value of the atomic object.

by

The differences are that the order parameter may make the memory consistency less strict than memory_order_seq_cst, *object is volatile qualified, the effect of updating *object is sequenced with respect to return from the call, and the value yielded by a compound assignment operator is the updated value of the object, whereas the value returned by the atomic_fetch and modify generic functions is the previous value of the atomic object.