7

My program is simple and I want to use atomic type. It works with int or double but it doesn't work with std::string.

#include <iostream>
#include <atomic>
#include <string>

int main()
{
    std::atomic<int> test(0);  // works
    std::cout<<test;  // will print 0

    return 0;
}

If I change to

std::atomic<std::string> test("0");

It will give this error

/usr/include/c++/6/atomic: In instantiation of ‘struct std::atomic >’: main.cpp:16:34:
required from here /usr/include/c++/6/atomic:178:7: error: static assertion failed: std::atomic requires a trivially copyable type static_assert(__is_trivially_copyable(_Tp), ^~~~~~~~~~~~~

I've tested the code with C++ 17, C++ 14 and C++ 11. Following this thread Does std::atomic<std::string> work appropriately? the atomic string should work properly, but I got this error. What's the reason behind this? And how to use std::atomic<std::string> properly?

curiousguy
  • 8,038
  • 2
  • 40
  • 58
gameon67
  • 3,981
  • 5
  • 35
  • 61
  • 1
    It seems to me that you are misreading the answer. The diagnostic is not required, but std::atomic requires a trivially copyable type and std::string is not one. – AProgrammer Nov 14 '19 at 08:50
  • Since the answer in the linked question directly answers this question (even though the op appears to have misunderstood it), I'll vote to close as a duplicate. To the op : re-read the answer there carefully. It does *not* say that `std::atomic` should work. It says that if it *does* work (or more accurately, if no diagnostic is generated), it's either undefined behavior or an implementation extension (with the latter being unlikely). – Sander De Dycker Nov 14 '19 at 08:59
  • @SanderDeDycker the OP of the that post used ` std::atomic atomicString;` and worked. I think it worked long time ago and now it doesn't work – gameon67 Nov 14 '19 at 09:01
  • @gameon67 : as I said : you misunderstood. It didn't *work* - it *appeared* to work because there was no diagnostic issued for it, but it was actually undefined behavior. Remember that just because code (with undefined behavior) compiles, it does not mean it does what you want. It might, but in the case of `std::atomic`, it probably doesn't. – Sander De Dycker Nov 14 '19 at 10:05
  • @SanderDeDycker I see, just read the link 1 more time and I understand what you mean. – gameon67 Nov 14 '19 at 11:06
  • Why would you want this? It's not going to be lock_free on any mainstream C++ implementation even if it were supported. – Peter Cordes Nov 16 '19 at 05:13

1 Answers1

10

std::string cannot be used with std::atomic as it is not TriviallyCopyable

See explanation here: https://en.cppreference.com/w/cpp/atomic/atomic

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:

https://en.cppreference.com/w/cpp/named_req/TriviallyCopyable

Nir
  • 1,608
  • 1
  • 17
  • 29