thread-safe local static variable initialization

Christophe de Dinechin ddd at cup.hp.com
Tue Jun 8 17:24:03 UTC 1999


Mike,.


>From your explanation, I understand that you consider protecting  
static initializations unnecessary. Initially, I thought you could  
read the standard that way. Now, I believe you can only if you accept  
that threaded and non-threaded code behaves completely differently.  
Consider:

	void f() {
		static int i = 0;
		static int j = i++;
		cout << i << j;
	}

Since the int ++ operator cannot throw an exception, the standard  
mandates that the output be 1 and 0 for all calls of f() in any  
non-threaded code.

You cannot ensure that in a threaded case without locking the  
initialization of j (the initialization of i can occur outside of f).  
That's because "[the] an object is considered initialized upon the  
completion of its initialization". While i++ is executing, another  
thread can therefore enter the static initialization. In the end, for  
a threaded program using f(), i and j can be anything (they could  
even be non consistent, that is 27 and 13).

Of course, you can say that having threads in the first place brings  
you in Undefined Land, but I'd prefer the above code to be  
consistent between threaded and non-threaded cases. It seems hard to  
require users to lock the above code.


The semantics currently implemented in the HP aC++ compiler is as follows:
- No two thread can enter a static initialization at the same time
- Threads are blocked until immediately after the static  
initialization either succeeds or fails with an exception.

There are details of our implementation that I disagree with, but in  
general, the semantics seem clear and sane, not as convoluted as you  
seemed to imply. In particular, it correctly covers the case where  
the static initialization fails with an exception. Any thread at that  
point can attempt the initialization.

> One can, of course, make any extension to the language, but in  
this case I
> think the extension invalidates some otherwise valid code.

If that's the case, this would make it a serious problem worth  
bringing to the committee. I could not find a case, though, that does  
not involve recursion (undefined) or setjmp/longjmp (I'm not sure it  
is undefined unless any automatic object requires destruction  
[lib.support.runtime]/4... maybe we could have a problem here)


Thank you in advance for your comments.
Christophe




More information about the cxx-abi-dev mailing list