Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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:

  • https://godbolt.org/z/ozhWuq
  • https://godbolt.org/z/tFKG5f

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

like image 949
hexiecs Avatar asked Jan 01 '23 23:01

hexiecs


1 Answers

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

like image 159
YSC Avatar answered Jan 12 '23 12:01

YSC