static member initialization

F

Frank Neuhaus

(Sorry I accidently submitted the question twice)

Hi
I've got a question on the initialization of static member variables. I have
some class that has a static member variable (some std::vector<something>*)
and a static member function. In the cpp corresponding to the class, the
variable is initialized like this:
std::vector<something>* TestClass::myStaticVar=new std::vector<something>();
Now my static function does something with this vector. I have observed
cases where the "myStaticVar" has a value of 0 when accessed from the static
function. I have tried to reproduce this behaviour in a smaller sample but
it always worked there for some reason.

Does anyone have an idea in what cases these static variables are properly
initialized?

Thanks alot
 
A

Andre Kostur

(Sorry I accidently submitted the question twice)

Hi
I've got a question on the initialization of static member variables.
I have some class that has a static member variable (some
std::vector<something>*) and a static member function. In the cpp
corresponding to the class, the variable is initialized like this:
std::vector<something>* TestClass::myStaticVar=new
std::vector<something>(); Now my static function does something with
this vector. I have observed cases where the "myStaticVar" has a value
of 0 when accessed from the static function. I have tried to reproduce
this behaviour in a smaller sample but it always worked there for some
reason.

Does anyone have an idea in what cases these static variables are
properly initialized?

Perhaps you're running into the issue of the indeterminate order in which
globals are initialized between translation units?

Are you trying to access the the static variable before main() starts?
 
F

Frank Neuhaus

Perhaps you're running into the issue of the indeterminate order in which
globals are initialized between translation units?

Are you trying to access the the static variable before main() starts?

Mhhh I think that may be it. It is initialized from a global variable
definition (static int something=MyClass::someFunc() ) somewhere else in the
code. Say Iam doing it like this:
std::vector<int>* MyClass::myStaticVar=0;
int MyClass::someFunc()
{
if (!myStaticVar)
myStaticVar=new std::vector<int>();
// do sth with myStaticVar
}

Now if myStaticVar is initialized after the someFunc is called, the pointer
in myStaticVar could be overwritten by the initialization, right?
So what if I do:
std::vector<int>* MyClass::myStaticVar;
Will it also get overwritten?

Is there any "safe" way to achieve the desired behaviour?

Thanks
 
F

Frank Neuhaus

It seems from the above that
* Only someFunc (plus possibly functions called by someFunc) uses the
var.

Thats not correct unfortunately. The static variable is used to make a list
of all classes of a certain type.
* The use of a pointer is not from any particular reason, i.e. it's not
in
order to circumvent ordinary lifetime rules (destruction order).

The pointer was an attempt to trick the initialization order thing. If the
vector is not a pointer, and it is accessed before it is initialized, it
actually crashes - with the pointer at least it doesnt crash (though im
assuming it is definately not a correct solution).

I have given this a bit more thought and came up with this:

class MyClass
{
public:
static void myfunc();
private:
static std::vector<int>& getvec() { static std::vector<int> v; return
v; };
};
}

now myfunc can simply do
void MyClass::myfunc()
{
std::vector<int>& myvec=getvec();
// do sth with myvec
}

That seems like a viable method to circumvent the problem, right?
 
A

Andre Kostur

Thats not correct unfortunately. The static variable is used to make a
list of all classes of a certain type.


The pointer was an attempt to trick the initialization order thing. If
the vector is not a pointer, and it is accessed before it is
initialized, it actually crashes - with the pointer at least it doesnt
crash (though im assuming it is definately not a correct solution).

I have given this a bit more thought and came up with this:

class MyClass
{
public:
static void myfunc();
private:
static std::vector<int>& getvec() { static std::vector<int> v;
return
v; };
};
}

now myfunc can simply do
void MyClass::myfunc()
{
std::vector<int>& myvec=getvec();
// do sth with myvec
}

That seems like a viable method to circumvent the problem, right?

Sure. In this case you're relying on the behaviour that static local
variables are initialized the first time that the execution crosses the
definition. (Which is Standard behaviour.)
 
F

Frank Neuhaus

That seems like a viable method to circumvent the problem, right?
Sure. In this case you're relying on the behaviour that static local
variables are initialized the first time that the execution crosses the
definition. (Which is Standard behaviour.)

Great. Thanks alot everyone :)
 
J

James Kanze

Thats not correct unfortunately. The static variable is used
to make a list of all classes of a certain type.
The pointer was an attempt to trick the initialization order
thing. If the vector is not a pointer, and it is accessed
before it is initialized, it actually crashes - with the
pointer at least it doesnt crash (though im assuming it is
definately not a correct solution).
I have given this a bit more thought and came up with this:
class MyClass
{
public:
static void myfunc();
private:
static std::vector<int>& getvec() { static std::vector<int> v; return
v; };
};
}
now myfunc can simply do
void MyClass::myfunc()
{
std::vector<int>& myvec=getvec();
// do sth with myvec
}
That seems like a viable method to circumvent the problem, right?

In a single threaded environment, or if you guarantee that
getvect is called at least once before threading starts. And if
you don't try to use the vector in any destructors to static
objects.

The pattern, here, is known as a singleton. I usually
implement it slightly differently, using a pointer:

std::vector< int >& getvec() ;
std::vector< int >* vector = &getvec() ;

std::vector< int >&
getvec()
{
if ( vector != NULL ) {
vector = new std::vector< int > ;
}
return *vector ;
}

This ensures that the getvec() function will be called at least
once before entering main (and thus, hopefully, before threading
is started), and that the vector itself is never destructed, so
it will be available in destructors as well.
 
F

Fred Zwarts

Frank Neuhaus said:
Thats not correct unfortunately. The static variable is used to make a list
of all classes of a certain type.


The pointer was an attempt to trick the initialization order thing. If the
vector is not a pointer, and it is accessed before it is initialized, it
actually crashes - with the pointer at least it doesnt crash (though im
assuming it is definately not a correct solution).

I have given this a bit more thought and came up with this:

class MyClass
{
public:
static void myfunc();
private:
static std::vector<int>& getvec() { static std::vector<int> v; return
v; };
};
}

now myfunc can simply do
void MyClass::myfunc()
{
std::vector<int>& myvec=getvec();
// do sth with myvec
}

That seems like a viable method to circumvent the problem, right?

Yes, but there is still a problem when the program ends.
How do you make sure that the static vector v is not destructed too early?
If myfunc is used in the destructor of another static object,
it might be that v has been destructed already.
Therefore I use a similar method, but the code of getvec looks like

{
static std::vector<int> *v = new std::vector<int>;
return *v;
}

The disadvantage of this is that v is never destructed.
Which in many cases does not harm.
 

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,769
Messages
2,569,582
Members
45,066
Latest member
VytoKetoReviews

Latest Threads

Top