5
void HelloWorld()
{
   static std::atomic<short> static_counter = 0;
   short val = ++static_counter; // or val = static_counter++;
}

If this function is called from two threads,

Can the local variable val be 1 in both threads? or (0 if static_counter++ is used?)

Gam
  • 1,254
  • 1
  • 9
  • 18
  • 1
    Possible duplicate http://stackoverflow.com/questions/8102125/is-local-static-variable-initialization-thread-safe-in-c11 – user2807083 Mar 28 '16 at 09:40
  • @user2807083 That is not the question. I know static_counter will be initialized safely. The c++11 standard requires that. I'm talking about val, which is not static.. – Gam Mar 28 '16 at 09:42
  • 1
    I think here it is nothing about your local `var`, but all about ++ operator applied to static variable. So I think the right question is "Is increment of atomic variable thread safe?" – user2807083 Mar 28 '16 at 09:44
  • Your question is about the thread safety of the *static* variable, not the local variable. – user207421 Mar 28 '16 at 09:47

2 Answers2

2

No. The only way val could have the same value in both threads is if the two atomic operations overlapped. By definition, atomic operations cannot overlap.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
2

Can the local variable val be 1 in both threads?

No. ++static_counter is equivalent to:

 fetch_add(1)+1

which cannot return same value for two (or more) threads because fetch_add is executed atomically.

Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • Does the same apply for static_counter++ ? – Gam Mar 28 '16 at 09:49
  • Yes. That is equivalent to `fetch_add(1)`. Please read [the doc](http://en.cppreference.com/w/cpp/atomic/atomic/operator_arith) for more details. – Nawaz Mar 28 '16 at 09:49
  • There are two things involved, the construction of the `static_counter` object and the increment operation. The latter is guaranteed to be atomic, but according to the link in the comments, construction isn't. – Ulrich Eckhardt Mar 28 '16 at 10:06
  • @UlrichEckhardt: Construction is guaranteed by C++11 spec, by the core language. – Nawaz Mar 28 '16 at 10:26
  • @nawaz there are global variabke ctor order problems: if called prior to main, what guaranteee that the atomic has been constructed is there? – Yakk - Adam Nevraumont Mar 28 '16 at 10:33
  • 1
    @Phantom Saying that one operation can be implemented as two divisible operations is the same as saying the operation isn't atomic. But we know the operation is atomic. – David Schwartz Mar 28 '16 at 11:03
  • @Yakk: I think the `static` keyword guarantees that no two threads can enter into the constructor. See the quote from the spec [in the accepted answer here](http://stackoverflow.com/questions/8102125/is-local-static-variable-initialization-thread-safe-in-c11) (and the comments as well) – Nawaz Mar 28 '16 at 11:08
  • @nawaz sorry, they edited since I had read it. It did not used to be static. – Yakk - Adam Nevraumont Mar 28 '16 at 13:09