Reputation: 1045
According to C11 § 6.5.2.3
Accessing a member of an atomic structure or union object results
in undefined behavior.
This makes sense since you cannot access a whole structure in general. Still why is _Atomic
then also a type qualifier and not only a type specifier?
In other words what is the purpose of a structure which is qualified as _Atomic
? I'm not allowed to either read or write to any element of it.
#include <stdatomic.h>
struct {
int x;
} _Atomic foo;
int main(void) {
foo.x = 42; // write error
return foo.x; // read error
}
Both accesses of foo.x
result in a warning/error in GCC/Clang---which is perfectly fine w.r.t. the C11 standard. Why would I want to qualifier then a structure as _Atomic
?
Upvotes: 4
Views: 1025
Reputation: 78923
You can not access individual members, but always the structure as a whole. Accessing parts of something that is meant to be an atomic unit, makes not much sense, I think.
A typical use case for an atomic structure is the combination of two pointers, e.g. the head and tail of a list. To manipulate such a struct
you would have to copy the current value from the atomic to a temporary, modify that, and then copy back. By that you'd always have a guarantee that the stored value is consistent at any time.
Per default all such operations on a whole atomic struct
have sequential consistency.
Upvotes: 3
Reputation: 81179
Some implementations might be able to guarantee atomic behavior for structures meeting certain criteria. I don't know whether any implementations that did so actually existed before the publication of the C11 Standard, but it would certainly seems plausible. If an implementation usefully supported such structures, it would have been rather annoying for the Standard to demand that they be treated as a constraint violation.
It would have been helpful if the Standard mandated, or at least suggested, that implementations treat as constraint violations any attempts to define atomic structures for which they cannot offer proper semantics, but for whatever reason the authors of the Standard seem extremely loath to recognize a category of programs that would be rejected by some implementations but have defined behavior on implementations that don't reject it. A good standard should seek to maximize the number of useful programs that would fall into that category, but the Standard instead tends to regard constructs which some implementations will support and others won't as Undefined Behavior, letting implementations support them or not at their leisure, but not offering any safe way to determine whether they are supported.
Upvotes: 0