Automatic locking for C++ local static initialization

Martin von Loewis loewis at informatik.hu-berlin.de
Mon Aug 7 09:49:55 UTC 2000


[...]
> One of those paths enters through function f, which defines some static
> data, one of which is constructed using function g, which is part of
> the cluster; others enter elsewhere and eventually call f.
[...]
> 	Thread 1		Thread 2
> 	--------		--------
> 	call h
> 	acquire M
> 				call f
> 				call g
> 				try to acquire M (wait)
> 	call f
> 	call g
> 	acquire M recursively
> 	finish initialization
> 	exit g, f
> 	release M		
> 	exit h			acquire M
> 				initialization is done
> 				release M
> 				exit g, f
>
> Everything has worked exactly as the programmer intended.

I believe this example is flawed, in that it violates a core C++
principle.

You haven't detailed the exact static variable, but assume it is like

struct A{
  A(int);
  ~A();
};

int g();

void f(){
  static A a(g());
}

which matches the description "constructed through function g". In you
control flow, g is invoked twice. Consequently, A::A(int) is invoked
twice as well. As a result, two constructors have been run to
initialize f()::a. However, at the end of the program, only one
destructor will be run to destroy a.

So this example violates the principle "exactly one destructor call
for each complete constructor call"; I'd claim this is *not* what the
programmer intended.

So it seems that the programmer can chose between a faulty constructor
semantics or a deadlock. Which of these is better is anybody's guess,
but it seems to me that the error is in the program.

Regards,
Martin




More information about the cxx-abi-dev mailing list