How does magic statics ensure that the right side is only executed once?

If I have

atomic<int> cnt=0;

int get_int() noexcept
{
   cnt++;
   return rand();
}

      

and then:

void func()
{
   static const auto value = get_int();
}

      

I know that value

there will be no race conditions on initialization , but I don't know if it get_int()

will be called once or if it will cnt

be 1 in my example (not 2, 3, 4 or 5).

Suppose there are several threads coming in func()

, but get_int

only has one callsite in func()

.

+3


source to share


2 answers


C ++ 11 guarantees there won't be any race conditions N3797 - Β§6.7 / 4:

An implementation is allowed to perform early initialization of other block scope variables with static or thread storage duration under the same conditions as the implementation is allowed to statically initialize a variable with static or thread storage duration in the namespace (3.6.2). Otherwise, such a variable initialized first time control passes through its declaration; such a variable is considered initialized by the completion of its initialization. If initialization is completed by throwing an exception, the initialization is not complete, so it will be checked again the next time the control enters the declaration. If control enters the declaration concurrently when the variable is initialized, the concurrent execution must wait for the initialization to complete.92 If control re-enters the declaration recursively while the variable is initialized, the behavior is undefined. [Example:

int foo(int i) {
  static int s = foo(2*i); // recursive call - undefined
  return i+1;
}

      

- end of example]



It is not re-entry, but thread safe. Make sure there are no other parts of the code that will be called get_int()

before func()

anyway.

+8


source


get_int()

will only be called once from that line, but given your code, get_int()

it could be called in advance from different places in your code.



+1


source







All Articles