Search code examples
c++thread-safetystdatomicexception-safety

How is std::atomic<T>::operator= implemented for immutable types?


I've learned that one way to communicate between threads is to share some atomic data structure. For example:

struct Point {
    int const x, y;
};

std::atomic<Point> some_point_in_shared_memory{Point{0, 0}};

Despite Point::operator=(Point const &) being deleted, there seems to be no problem calling the assignment operator for std::atomic<Point> as follows:

some_point_in_shared_memory = Point{1, 2};

How can this operation be implemented?

One solution I might think about is using placement new to construct a new object on top of the old one, but apparently it is not exception safe. Or is it okay because Point is trivially-copyable?


Solution

  • From cppreference:

    The primary std::atomic template may be instantiated with any TriviallyCopyable type T satisfying both CopyConstructible and CopyAssignable. The program is ill-formed if any of following values is false:

    std::is_trivially_copyable<T>::value
    std::is_copy_constructible<T>::value
    std::is_move_constructible<T>::value
    std::is_copy_assignable<T>::value
    std::is_move_assignable<T>::value
    

    Your T is not CopyAssignable, and this line

    some_point_in_shared_memory = Point{1, 2};
    

    is ill-formed. There should be a compiler error. Unfortunately I didn't get GCC to emit an error or warning (-pedantic -Wpedantic -pedantic-errors -Wall -Werror=pedantic no effect).