Submitter: Fred J. Tydeman (USA)
Submission Date: 2013-10-22
Subject:Possible defect report: ATOMIC_VAR_INIT
Related: DR
422and DR
427
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?
There is no mention of state in 7.17.2.1#2 in the use of ATOMIC_VAR_INIT.
The ATOMIC_VAR_INIT macro expands to a token sequence suitable for initializing an atomic object of a type that is initialization-compatible with value. An atomic object with automatic storage duration that is not explicitly initialized using ATOMIC_VAR_INIT is initially in an indeterminate state; however, the default (zero) initialization for objects with static or thread-local storage duration is guaranteed to produce a valid state.
while there is in 7.17.2.2 atomic_init #2:
The atomic_init generic function initializes the atomic object pointed to by obj to the value value, while also initializing any additional state that the implementation might need to carry for the atomic object.
I hope this is an oversight in 7.17.2.1#2.
That term is used in 7.17.2.1#2, but not defined anywhere in the C standard (that I can find).
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.
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?
I have been told that C's 7.17.2.1#2:
...; however, the default (zero) initialization for objects with static or thread-local storage duration is guaranteed to produce a valid state.
is not in C++. If true and assuming that the two languages should be the "same" here, should this be deleted from C? Added to C++?
DR 422 is somewhat related to this issue.
Suggested Technical Corrigendum
Add to 7.17.2.1#2 as part of the first sentence:
... while also initializing any additional state that the implementation might need to carry for the atomic object ...
No suggestion on "initialization-compatible".
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.
No suggestion on the requirements mis-match between C and C++.