The return value of sizeof(atomic<T>)
is not always equal to the return value of sizeof(T)
, based on following sentence from [atomics.types.generic]/p9:
Note: The representation of an atomic specialization need not have the same size as its corresponding argument type. Specializations should have the same size whenever possible, as this reduces the effort required to port existing code
Sometimes they are equal, like this:
struct A {
char i;
const char padding[3];
int j;
};
A a;
a.i = 1;
a.j = 2;
A b;
b.i = 3;
b.j = 4;
std::atomic<A> A_atomic(a);
sizeof(A_atomic)
is 8, and sizeof(A)
is 8 too.
A_atomic.compare_exchange_weak(a,b)
returns true.
A_atomic.is_always_lock_free
returns true.
When I add an int
variable, they are not the same:
struct A {
char i;
const char padding[3];
int j;
int k;
};
A a;
a.i = 1;
a.j = 2;
A b;
b.i = 3;
b.j = 4;
std::atomic<A> A_atomic(a);
sizeof(A_atomic)
is 16, and sizeof(A)
is 12.
A_atomic.compare_exchange_weak(a,b)
returns false.
A_atomic.is_always_lock_free
returns true.
What happened to std::atomic<A>
when I added an int
?
How can I pick out the subtle difference between the two structs to align the memory layout in order to ensure CAS returns true?
My environment is:
- macOSX10.13
- clang-900.0.37
- x86_64-apple-darwin18.7.0
more info:
I add another int
variable like:
struct A {
char i;
const char padding[3];
int j;
int k;
int h;
}
sizeof(A_atomic)
is 16, and sizeof(A)
is 16.
A_atomic.compare_exchange_weak(a,b)
returns true.
A_atomic.is_always_lock_free
returns true.