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