N1567 Issues with Footnote 113

Blaine Garst, Jim Thomas

March 17, 2010


6.5.16.2 Compound assignment

A compound assignment of the form E1 op= E2 is equivalent to the simple assignment expression E1 = E1 op (E2), except that the lvalue E1 is evaluated only once, and with respect to an indeterminately-sequenced function call, the operation of a compound assignment is a single evaluation. If E1 has an atomic type, compound assignment is a read-modify-write operation with memory_order_seq_cst memory order semantics. 

Edit paragraph 3 footnote 113) as follows. This change clarifies that the right-hand argument is evaluated only once.  It also clarifies the intent that any exceptions that occur during intermediate failing computations should not accumulate in order to satisfy the equivalence of E1 op= E2 and E1 = E1 op (E2).

Here is the proposed change:

113) Where a pointer to an atomic object can be formed, and where E1 and E2 have integer type, this is equivalent to the following code sequence where T1 is the type of E1 and T2 is the type of E2:

T1* addr = &E1;

T1 tmp = *addr;

T2 val = (E2);

T1 result;

do {

      result = tmp op val;

} while (!atomic_compare_exchange_strong(addr, &tmp, result));

with result being the result of the operation.

If E1 or E2 are floating types, then exceptional conditions or floating-point exceptions encountered during discarded evaluations of result should be discarded in order to satisfy the equivalence of E1 op= (E2) and E1 = E1 op (E2).  For example, if Annex F is in effect, the floating types involved have IEC 60559 formats, and FLT_EVAL_METHOD defined as 0, the equivalent code would be

#include <fenv.h>

#pragma STDC FENV_ACCESS ON

fenv_t fenv;

T1 *addr = &E1;

T1 existing = *addr; // evaluate E1 only once

T2 val = E2;

T1 result;

feholdexcept(&fenv);

for (;;) {

      result = existing op val; 

      if (atomic_compare_exchange_strong(addr, &existing, result))

break;

      feclearexcept(FE_ALL_EXCEPT); 

}

feupdateenv(&fenv);

 

If FLT_EVAL_METHOD is not 0 then T2 must be a type with the range and precision to which E2 is evaluated in order to satisfy the equivalence of E1 op= (E2) and E1 = E1 op (E2).