7

Possible Duplicate:
Is static init thread-safe with VC2010?

I know that gcc and llvm-clang emit code to initialise local static variables in a threadsafe manner (which allows one to escape the static order initialisation fiasco by wrapping global statics in functions).

This msdn blog post, however, is the best documentation I can find of vcc's behaviour in these circumstances, and purports that static initialisation cannot ever be threadsafe, because the initialiser for a local static could recursively call into the same scope.

I don't buy this argument - it is clearly a programming error if the initialiser relies on its own result.

So, given that this article is from 2004, that gcc and clang can do it, and that the current msvc documentation is ambiguous (stating that 'assigning' to a local static isn't threadsafe, but nothing more):

Is the initialisation of local statics now threadsafe in MSVC?

If not, why not, since it is clearly possible for gcc to do this, but very difficult for the programmer to add in afterwards.

Community
  • 1
  • 1
James
  • 24,676
  • 13
  • 84
  • 130
  • Since thread safety at that point is not required by C++03, both compilers are just as correct in doing what they do. The only way to find out is to look at the generated code. Possibly it even depends on compiler flags (surely gcc lets one disable the used mutexes for when you want single threaded code) – PlasmaHH Sep 27 '11 at 10:56
  • @PlasmaHH Perhaps, but you'd expect it to be in the documentation - it's a very useful feature! – James Sep 27 '11 at 11:02
  • 1
    It is, at least in the gcc manpage. Don't know (and really don't care much) bout MSVC. – PlasmaHH Sep 27 '11 at 11:05

2 Answers2

1

I heard it is already implemented in vs2010, but can not find any reference. Anyway in c++0x standard such initializations are explicitly required to be thread-safe, so sooner or later ms would comply I guess.

Slava
  • 1,528
  • 1
  • 15
  • 23
  • 1
    It is *not* implemented in vs2010. According to https://msdn.microsoft.com/en-us/library/hh567368.aspx (which refers to the feature as "magic statics"), the first version of Visual Studio to implement this aspect of C++11 is vs2015. – Matthew May 30 '17 at 14:55
1

The C++0x Standard says:

§6.7 Declaration statement [stmt.dcl]

4/ The zero-initialization (8.5) of all block-scope variables with static storage duration (3.7.1) or thread storage duration (3.7.2) is performed before any other initialization takes place. Constant initialization (3.6.2) of a block-scope entity with static storage duration, if applicable, is performed before its block is first entered. 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.88

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 ]

88) The implementation must not introduce any deadlock around execution of the initializer.

As expected, it is quite complete.

However the fact is that even older versions of gcc already complied with this, and in fact do even better: in case of recursive initialization, an exception is thrown.

Finally, regarding a programmer adding it afterward: you can normally do it if you have something like Compare And Swap available, and use a sufficiently small variable, relying on zero-initialization of the variable to mark its non-computed state. However I do agree it's much easier if it's baked in.

I am afraid I stopped followed VC++ progresses though, so I don't know where it stands now. My only advice would be... look it up at assembly level.

Matthieu M.
  • 287,565
  • 48
  • 449
  • 722