9

May this global function suffer from static initialization fiasco?

template <typename TFn>
void ParallelFor(int iIni,int iFin,TFn Fn)    
{
  static const unsigned int NThread= std::thread::hardware_concurrency();
  // ...    
}
manlio
  • 18,345
  • 14
  • 76
  • 126
metalfox
  • 6,301
  • 1
  • 21
  • 43
  • 5
    Unrelated nitpick: note that your NThread variable will exist for each distinct instantiation of the function template. – rubenvb Jun 06 '16 at 07:03

1 Answers1

7

May this global function suffer from static initialization fiasco?

No, it wouldn't. You are safe... :-)

Quoting the C++ standard draft (emphasis mine)...

$6.7: 4: Dynamic initialization of a block-scope variable with static storage duration ([basic.stc.static]) or thread storage duration ([basic.stc.thread]) is performed 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

Also, see: Static local variables

Since your function is a function template template <typename TFn>, for each separate instantiation (substitution of TFn), static const unsigned int NThread = std::thread::hardware_concurrency(); will be evaluated

WhiZTiM
  • 21,207
  • 4
  • 43
  • 68
  • Cool. But what if the function is instantiated in the constructor of a static object ([link](https://isocpp.org/wiki/faq/ctors#static-init-order))? – metalfox Jun 06 '16 at 07:32
  • @metalfox, to your question: there wouldn't be any problem still! Remember, your static variable is in a *function block scope*. It is guaranteed to be initialized first time it is called at runtime by **whosoever**. (Reread the quoted paragraph). Your link deals with a different scenario i.e when the objects are in *global scope*: in that case your answer is in the [next section](https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-use) – WhiZTiM Jun 06 '16 at 09:11
  • @WhiZTiM. Thanks for your detailed answer. What I was worried about is that some implementation of `hardware_concurrency` might rely on a global/static variable, thus producing the fiasco. From your comments I deduce that it is either not possible or explicitly forbidden by the Standard. – metalfox Jun 06 '16 at 11:20