Thread safety problems with function scope static variables vs class static private members

H

Hicham Mouline

I have a function f that is called from multiple threads
I have the choice between setting a const int array as a static local in f()

void C::f() {
static const int keys[] = { 0, ...., 15 };
}

or as a private member of C

class C {
private:
static const int keys[] ;
};
const int C::keys[] = { 0....15 };



1 In theory?
Is there a risk that keys are initialized badly because keys is a static
local variable of f (keys init'ed only first time exec enters f)
while no risk when keys is a static member of C (because keys is init'ed
before runtime passes through main even)?
I know c++03 says nothing about threads. Can one still infer anything from
it?

2 In practise, (msvc, g++, intel....)
Do these make sure keys init as function local is ok, and as a member of C
also?

regards,
 
J

James Kanze

I have a function f that is called from multiple threads I
have the choice between setting a const int array as a static
local in f()
void C::f() {
static const int keys[] = { 0, ...., 15 };
}
or as a private member of C
class C {
private:
static const int keys[] ;};
const int C::keys[] = { 0....15 };
1 In theory?
Is there a risk that keys are initialized badly because keys
is a static local variable of f (keys init'ed only first time
exec enters f) while no risk when keys is a static member of C
(because keys is init'ed before runtime passes through main
even)? I know c++03 says nothing about threads. Can one still
infer anything from it?

No. In both cases, you have static initialization, which is
guaranteed to occur before anything else.
2 In practise, (msvc, g++, intel....)
Do these make sure keys init as function local is ok, and as a
member of C also?

As long as it is static initialization, there can be no problem.
Note that for it to be static initialization, the type in
question must be a POD, and all of the initialization
expressions must be constant expressions. But I regularly use
such things to avoid order of initialization issues.
 
F

Fred Zwarts

Hicham Mouline said:
I have a function f that is called from multiple threads
I have the choice between setting a const int array as a static local in f()

void C::f() {
static const int keys[] = { 0, ...., 15 };
}

or as a private member of C

class C {
private:
static const int keys[] ;
};
const int C::keys[] = { 0....15 };



1 In theory?
Is there a risk that keys are initialized badly because keys is a static
local variable of f (keys init'ed only first time exec enters f)
while no risk when keys is a static member of C (because keys is init'ed
before runtime passes through main even)?

Who says that threads are not created before main is started?
Thread safety is required even before main in started.
 
J

James Kanze

Hicham Mouline said:
I have a function f that is called from multiple threads
I have the choice between setting a const int array as a
static local in f()
void C::f() {
static const int keys[] = { 0, ...., 15 };
}
or as a private member of C
class C {
private:
static const int keys[] ;
};
const int C::keys[] = { 0....15 };
1 In theory?
Is there a risk that keys are initialized badly because keys
is a static local variable of f (keys init'ed only first
time exec enters f) while no risk when keys is a static
member of C (because keys is init'ed before runtime passes
through main even)?
Who says that threads are not created before main is started?

The coding guidelines.
Thread safety is required even before main in started.

If your coding guidelines allow creating threads in the
constructors of objects with static lifetime. Most I've seen
don't---threading is hard enough to get right without going out
of your way to make it more difficult.
 
J

Juha Nieminen

James said:
void C::f() {
static const int keys[] = { 0, ...., 15 };
}

No. In both cases, you have static initialization, which is
guaranteed to occur before anything else.

I thought that a static inside a function is initialized the first
time the function is called?

The above function might not be problematic with regard to thread
safety, but what about something like this:

void foo()
{
static SomeClass object;
...
}

Suppose that 'foo()' may be called from more than one thread. Can it
happen that 'object' is constructed more than once? (Worse: Can it
happen, that while the constructor of 'object' is being executed, a
second thread causes it to be called again?)

Assume that SomeClass, for example, allocates memory into a member
pointer, or does something else which would cause a serious malfunction
if the constructor were to be called more than once.
 
J

James Kanze

James said:
void C::f() {
static const int keys[] = { 0, ...., 15 };
}
No. In both cases, you have static initialization, which is
guaranteed to occur before anything else.
I thought that a static inside a function is initialized the
first time the function is called?

The standard explicitly says otherwise: "Objects of POD types
with static storage duration initialized with constant
expressions shall be initialized before any dynamic
initialization takes place." (§3.6.2/1).

In fact, in this case, the word static means what it says; such
variables are initialized statically, not dynamically.
The above function might not be problematic with regard to
thread safety, but what about something like this:
void foo()
{
static SomeClass object;
...
}

It depends on SomeClass, obviously. Does SomeClass use static
or dynamic initialization?
Suppose that 'foo()' may be called from more than one thread.
Can it happen that 'object' is constructed more than once?

Probably. I don't know what the next version of the standard
will say about it, but in current implementations, it's
undefined behavior to enter such a function from several
different threads without some sort of external synchronization.

But what does this have to do with static initialization?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,731
Messages
2,569,432
Members
44,835
Latest member
KetoRushACVBuy

Latest Threads

Top