Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do magic statics guarantee that right side is executed only 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 there will be no race condition on initialization of value, but I don't know if get_int() will be called once, or in my example will cnt be 1 (and not 2, 3, 4, or 5).

Assume multiple threads enter func() and get_int has only 1 callsite in func().

like image 744
NoSenseEtAl Avatar asked Jan 10 '23 12:01

NoSenseEtAl


2 Answers

C++11 guarantees that there will be no race condition N3797 - §6.7/4:

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

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

- end example ]

It's not re-entrant but thread-safe. Make sure there will not be other parts of the code that will call get_int() before func() anyway.

like image 97
Marco A. Avatar answered Jan 24 '23 18:01

Marco A.


get_int() will be called only once from that line , but given your code, get_int() could be called beforehand from different locations in the code.

like image 42
Gui Rava Avatar answered Jan 24 '23 17:01

Gui Rava