Submitter: Jens Gustedt
Submission Date: 2016-07-20
Reference Document: n2064
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
220.127.116.11 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.
The language and the library define a number of atomic operations (18.104.22.168, 6.5.16 and 7.17) operations on mutexes (7.26.4) and other library calls (7.22.3, 22.214.171.124, 7.26.5) that are specially identified as synchronization operations.
126.96.36.199 p9, for clarification replace:
Loads and stores of objects with atomic
types are done with
by the following
Unless specified otherwise, all operations
that affect objects with atomic types are done with
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.
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.
188.8.131.52 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
... to an object of any atomic integer or pointer type, as long as
C is valid for the left operand of the
FOOTNOTE: Thus none of these operations are permitted if
_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.
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
but the operation otherwise has no visible
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.
The differences are that
order parameter may make
the memory consistency less strict
volatile qualified, the effect of
*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.