Comparison semantics with std::atomic types

2019-02-27 02:33发布

问题:

I'm trying to find where the comparison semantics for the type T with std::atomic is defined.

I know that beside the builtin specializations for integral types, T can be any TriviallyCopyable type. But how do operations like compare_and_exchange_X know how to compare an instance of T?

I imagine they must simply do a byte by byte comparison of the user defined object (like a memcmp) but I don't see where in the standard this is explicitly mentioned.

So, suppose I have:

struct foo
{
  std::uint64_t x;
  std::uint64_t y;
};

How does the compiler know how to compare two std::atomic<foo> instances when I call std::atomic<foo>::compare_and_exchange_weak()?

回答1:

In draft n3936, memcmp semantics are explicitly described in section 29.6.5.

Note: For example, the effect of atomic_compare_exchange_strong is if (memcmp(object, expected, sizeof(*object)) == 0) memcpy(object, &desired, sizeof(*object)); else memcpy(expected, object, sizeof(*object));

and

Note: The memcpy and memcmp semantics of the compare-and-exchange operations may result in failed comparisons for values that compare equal with operator== if the underlying type has padding bits, trap bits, or alternate representations of the same value.

That wording has been present at least since n3485.

Note that only memcmp(p1, p2, sizeof(T)) != 0 is meaningful to compare_and_exchange_weak (failure guaranteed). memcmp(p1, p2, sizeof(T)) == 0 allows but does not guarantee success.



回答2:

It's implementation defined. It could just be using a mutex lock or it could be using some intrinsics on memory blobs. The standard simply defines it such that the latter might work as an implementation strategy.

The compiler doesn't know anything here. It'll all be in the library. Since it's a template you can go read how your implementation does it.



标签: c++ atomic