Static class member initialization question

M

Michael Klatt

I am working on a library which uses the GKS graphics package. I have
a Gks object which opens the GKS subsystem in its constructor:

// Gks.hpp

class Gks
{
public :
Gks();
};


--------------------

// Gks.cpp

#include "Gks.hpp"
Gks::Gks()
{
// open GKS subsystem
}


I have several types of object which need the GKS subsystem to be
opened before they can be created. I need something like a global
static Gks object, but since this is tricky to do in a library I'm
trying a solution that uses inheritence. All classes which need a
static Gks object derive from GksInit:

// GksInit.hpp
#include "Gks.hpp"

class GksInit
{
public :
virtual ~GksInit() {}

protected :
GksInit();

private :
static const Gks ourGks;
};

--------------------------

//GksInit.cpp
#include "GksInit.hpp"

const Gks GksInit::eek:urGks; // make sure GKS gets initialized

GksInit::GksInit() {}


----------------

// Workstation.hpp
// GKS needs to be initialized before a Workstation can be created
#include "GksInit.hpp"

class Workstation : public GksInit
{
...
};


This all seems to work as desired, but here is my problem/question.
If I inline the GksInit constructor in the header file, the
GksInit::eek:urGks static member never gets constructed. Why is this?
 
L

lilburne

Michael said:
This all seems to work as desired, but here is my problem/question.
If I inline the GksInit constructor in the header file, the
GksInit::eek:urGks static member never gets constructed. Why is this?

Static member variables are initialized before main is
called. The inheritance GksInit and construction of a
GksInit has nothing to do with it.

Are you sure you haven't removed the

'const Gks GksInit::eek:urGks;'

declaration from the cpp file?
 
A

Andrey Tarasevich

lilburne said:
Static member variables are initialized before main is
called. The inheritance GksInit and construction of a
GksInit has nothing to do with it.
...

No, dynamically initialized non-local objects are guaranteed to be
initialized before the first use of any function defined in the same
translation unit. This means that non-local objects, which are defined
in the same translation unit with 'main', are guaranteed to be
initialized before 'main' is called. But there's no such guarantee for
non-local objects defined in other translation units.
 
L

lilburne

Andrey said:
No, dynamically initialized non-local objects are guaranteed to be
initialized before the first use of any function defined in the same
translation unit. This means that non-local objects, which are defined
in the same translation unit with 'main', are guaranteed to be
initialized before 'main' is called. But there's no such guarantee for
non-local objects defined in other translation units.

True you can't guarantee initialisation order across
translation usits, but doesn't his GksInit::eek:urGks having
static storage duration guarantee it being initialized
before any dynamic initialization occurs?
 
M

Michael Klatt

I am working on a library which uses the GKS graphics package. I have
a Gks object which opens the GKS subsystem in its constructor:

// Gks.hpp

class Gks
{
public :
Gks();
};


--------------------

// Gks.cpp

#include "Gks.hpp"
Gks::Gks()
{
// open GKS subsystem
}


I have several types of object which need the GKS subsystem to be
opened before they can be created. I need something like a global
static Gks object, but since this is tricky to do in a library I'm
trying a solution that uses inheritence. All classes which need a
static Gks object derive from GksInit:

// GksInit.hpp
#include "Gks.hpp"

class GksInit
{
public :
virtual ~GksInit() {}

protected :
GksInit();

private :
static const Gks ourGks;
};

--------------------------

//GksInit.cpp
#include "GksInit.hpp"

const Gks GksInit::eek:urGks; // make sure GKS gets initialized

GksInit::GksInit() {}

I just want to reiterate my question. The code I have posted here
seems to work as I expect. However, if I inline the GksInit
constructor in the header file, the constructor for static member
ourGks never gets called. The only difference is the inlined
constructor; the GksInit source file still contains the definition of
ourGks.

Why does it matter if the GksInit() is inlined or defined in the
source file?
 
V

Victor Bazarov

Michael Klatt said:
(e-mail address removed) (Michael Klatt) wrote in message

I just want to reiterate my question. The code I have posted here
seems to work as I expect. However, if I inline the GksInit
constructor in the header file, the constructor for static member
ourGks never gets called. The only difference is the inlined
constructor; the GksInit source file still contains the definition of
ourGks.

Why does it matter if the GksInit() is inlined or defined in the
source file?

Sounds like a bug in the compiler. Perhaps it discards any consts
if they are not used anywhere else in the system. See if using
a different compiler would fix the problem.

Victor
 
J

Jesper Madsen

I think you should make a function instead, it usually helps, not all
compilers like statics floating around.

Just do a:
Gtk& GtkInstance(){
static Gtk ourGtk;
return ourGtk;
}

Jesper
 

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,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top