Search code examples
c++std-pairstdatomic

Why is it not possible to instantiate an atomic pair?


When compiling the following piece of code (gcc-4.8, --std=c++11):

#include <atomic>
#include <utility>
#include <cstdint>

struct X {
    std::atomic<std::pair<uint32_t, uint32_t>> A;
};

I get the following compilation error:

/usr/local/include/c++/4.8.2/atomic:167:7: error: function
 'std::atomic<_Tp>::atomic() [with _Tp = std::pair<unsigned int, unsigned int>]'
 defaulted on its first declaration with an exception-specification that differs
 from the implicit declaration 'constexpr std::atomic<std::pair<unsigned int, 
unsigned int> >::atomic()'

With a more recent compiler (gcc-9 with --std=c++17), I get:

In instantiation of 'struct std::atomic<std::pair<int, int> >':
  error: static assertion failed: std::atomic requires a trivially copyable type
static_assert(__is_trivially_copyable(_Tp),

demos:

I can't figure out the reason why; can anyone help me please?


Solution

  • std::atomic<T> requires T to be TriviallyCopyable.

    You cannot define an std::atomic<std::pair<...>> because std::pair is not trivially copiable. For more information about that, read Why can't std::tuple be trivially copyable?.

    As a workaround, you can define your own simplified trivially copiable pair:

    #include <atomic>
    #include <cstdint>
    
    struct X
    {
        using pair = struct { std::uint32_t first; std::uint32_t second; };
        std::atomic<pair> A;
    };
    

    demo: https://godbolt.org/z/epPvOr