Submitter: Fred J. Tydeman (USA)
Submission Date: 2013-10-22
Source: WG14
Reference Document: N1777
Version: 1.0
Date: April 2014
Subject: ATOMIC_VAR_INIT (issues 3 and 4)
Related: DR
422 and DR
427
Summary
I see several issues with ATOMIC_VAR_INIT. They could be turned into one combined defect report, or separate defects, or folded into DR 422.
Consider the following code:
#include <stdatomic.h>
int main(void){
atomic_int guide1 = ATOMIC_VAR_INIT(42); /* known value(42); WHAT STATE? */
atomic_int guide2; /* indeterminate value; indeterminate state */
atomic_int guide3 = 42; /* known value(42); indeterminate state */
static atomic_int guide4; /* known value(0); valid state */
static atomic_int guide5 = 42; /* known value(42); valid state */
atomic_int guide6;
atomic_init(&guide6, 42); /* known value(42); initialized state */
return 0;
}
What is the status of the additional state carried for guide1?
Is the state of guide1 the same as what guide6 has? If yes, does "initialization-compatible" mean do the same thing as if atomic_init() of the same object with the same value?
(Issue 3 from N1777)
ATOMIC_VAR_INIT is not usable in assignment to an atomic object.I see no difference between:
atomic_int guide = ATOMIC_VAR_INIT(42);
and
atomic_int guide; guide = ATOMIC_VAR_INIT(42);
I would hope that initialization (which looks like an assignment in a declaration) and a simple assignment would be equivalent and ATOMIC_VAR_INIT could be used in either context.
(Issue 4 from N1777)
What should happen if ATOMIC_VAR_INIT(value) is used in context other than initializing an atomic object of the same type as the value?Should it be undefined behaviour? A constraint violation? Just the value value converted to the type of the object?
atomic_float f = ATOMIC_VAR_INIT(42); /* type mis-match */ int nonAtomic = ATOMIC_VAR_INIT(42); /* non-atomic object */ if( ATOMIC_VAR_INIT(42) ){...}; guide1 = 1729 + ATOMIC_VAR_INIT(42) * 3; void func( atomic_int ai ); /* function parm/arg */ func( ATOMIC_VAR_INIT(42) ); /* DR 427 is now making this initialization (not assigment) */
DR 427 is changing how a function parameter is getting its value from the actual argument from assignment to initialization (to get around const). Would this initialization be a valid context for ATOMIC_VAR_INIT?
Suggested Technical Corrigendum
In the first sentence of 7.17.2.1#2, after
suitable for initializing
add the words
or assigning to
Add to 7.17.2.1 as a constraint or a new paragraph between 3 and 4:
If ATOMIC_VAR_INIT is used in a context other than initialization [or assignment] of an atomic object of a compatible type of the value, the behaviour is undefined.
Proposed Committee Response
The ATOMIC_VAR_INIT macro prepares an atomic value that includes any extra state necessary for a non-lock-free type. Initialization, by definition, ignores all previous state. Assignment must honor the extra state that would indicate another atomic operation in progress; such an assignment takes the non-atomic corresponding value resulting from removing all qualifiers including atomic from the value expression, and will manipulate the extra state held in the object to assure proper atomic assignment semantics. ATOMIC_VAR_INIT produces a value appropriate for initialization because it will have any necessary extra state, whereas a value suitable for assignment is the non-qualified version of the assignment expression.All uses of ATOMIC_VAR_INIT other than for initialization result in implicitly undefined behavior.