How to initialize a static structure?

B

Bob Altman

Hi all,

I have a private static structure in a C++ class (it's a CRITICAL_SECTION
structure) that needs to be initialized by passing its address to a routine
(InitializeCriticalSection). Since C++ apparently doesn't allow a static
constructor routine, how do I initialize my static member variable prior to
allowing any instances to be constructed?

TIA - Bob
 
B

Brian Muth

Since C++ apparently doesn't allow a static
constructor routine, how do I initialize my static member variable prior to
allowing any instances to be constructed?

A static member variable can certainly have a constructor, and this will be called automatically when the DLL is loaded.
 
C

Carl Daniel [VC++ MVP]

Bob said:
Hi all,

I have a private static structure in a C++ class (it's a
CRITICAL_SECTION structure) that needs to be initialized by passing
its address to a routine (InitializeCriticalSection). Since C++
apparently doesn't allow a static constructor routine, how do I
initialize my static member variable prior to allowing any instances
to be constructed?

struct CriticalSection : CRITICAL_SECTION
{
public:
CriticalSection()
{
::InitializeCriticalSection(this);
}

~CriticalSection()
{
::DeleteCriticalSection(this);
}
};

Now, just use CriticalSection instead of CTRITICAL_SECTION when declaring
your variables. There are a million ways to twist this - this is just one
example of how you can get static constructor behavior for your critical
section variables.

-cd
 
B

Bob Altman

That's tricky... Instead of initializing the structure in my (non-existent)
static constructor, we're creating a self-initializing structure. I like
it! Thanks!

So, as an academic question: Suppose I have an int variable that needs to
be initialized by passing its address to some routine. Is there some tricky
way to create a self-initializing static int variable?

- Bob
 
C

Carl Daniel [VC++ MVP]

Bob said:
That's tricky... Instead of initializing the structure in my
(non-existent) static constructor, we're creating a self-initializing
structure. I like it! Thanks!

That's the C++ way. The C# static constructor is a crutch to smooth over
one of the warts left by not having deterministic construction and
destruction - not to mention initialized static variables.
So, as an academic question: Suppose I have an int variable that
needs to be initialized by passing its address to some routine. Is
there some tricky way to create a self-initializing static int
variable?

Sure - just make a class to do it.

template <typename T, void (*fn)(T*)> struct init_t
{
init_t()
{
(*fn)(m_t);
}

operator T&
{
return m_t;
}

private:
T m_t;
};


// An initialization function
extern void some_init_fn(int* p);

// Helper typedef
typedef init_t<int,some_init_fn> InitInt;

// An int that's initialized by passing it's address to that function
InitInt my_initialized_int;

Again, one of a hundred different variations on a theme. If you truly want
the int to be an independent variable, then remove the private member and
pass it as a constructor parameter instead. Then you have to declared two
variables - one int and one init_t<int,void(*)(int*)>.

Boost (and various other template libraries) have pre-made portable,
reusable solutions to these problems and many more.

-cd
 
B

Bob Altman

Thanks Carl!

- Bob

Carl Daniel said:
That's the C++ way. The C# static constructor is a crutch to smooth over
one of the warts left by not having deterministic construction and
destruction - not to mention initialized static variables.


Sure - just make a class to do it.

template <typename T, void (*fn)(T*)> struct init_t
{
init_t()
{
(*fn)(m_t);
}

operator T&
{
return m_t;
}

private:
T m_t;
};


// An initialization function
extern void some_init_fn(int* p);

// Helper typedef
typedef init_t<int,some_init_fn> InitInt;

// An int that's initialized by passing it's address to that function
InitInt my_initialized_int;

Again, one of a hundred different variations on a theme. If you truly
want the int to be an independent variable, then remove the private member
and pass it as a constructor parameter instead. Then you have to declared
two variables - one int and one init_t<int,void(*)(int*)>.

Boost (and various other template libraries) have pre-made portable,
reusable solutions to these problems and many more.

-cd
 

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

Top