Order of Static Members

L

Luther Baker

Hi,

Is the order of initialization guaranteed for static members as it is
for instance members?

Namely, the order they appear the in the declaration?

ie:

foo.h:

class Foo
{

....

private:

static std::string header_label;

static size_t header_len;

};

....

foo.cpp

std::string Foo::header_label ("vendor-product-0.1.1");

//
// Can I depend on header_label to be initialized at this point?
//
size_t Foo::header_len = header_label.length() +
2*(sizeof(AddressSize));


Thanks,

-Luther
 
B

Bob Hairgrove

Hi,

Is the order of initialization guaranteed for static members as it is
for instance members?

The C++ Standard articles which specify this are as follows:

<quote>
"9.4.2 Static data members
....
7 Static data members are initialized and destroyed exactly like
non-local objects. (3.6.2, 3.6.3)"
</quote>

Since 3.6.2 and 3.6.3 are rather lengthy, I'll leave the rest up to
you to find out by referring to the Standard.

In short, static objects initialized with a constant expression (or
zero-initialized) are done before any static objects initialized by
dynamic initialization (e.g. by a function call). Dynamically
initialized objects are initialized "in the order in which their
definition appears in the translation unit". IOW, this is different
than member data which is initialized in the order of the
*declaration* of the members.

Most compilers have proprietary means of ensuring that certain global
initializations are done before anything else, usually involving some
#pragma expression. E.g. in Borland C++ Builder, it's "#pragma
startup(<some number>)", M$VC++ has "#pragma compile" or something
similar.

Therefore, the linkage order, and perhaps the compiler options, will
also have an influence on the order in which static objects are
created and destroyed.

(If I have left anything out or misinterpreted something, I apologize
.... the C++ standard will have the last word. CAVEAT EMPTOR...).
 
G

Gianni Mariani

Luther said:
Hi,

Is the order of initialization guaranteed for static members as it is
for instance members?

Namely, the order they appear the in the declaration?

ie:

foo.h:

class Foo
{

....

private:

static std::string header_label;

static size_t header_len;

};

....

foo.cpp

std::string Foo::header_label ("vendor-product-0.1.1");

//
// Can I depend on header_label to be initialized at this point?
//
size_t Foo::header_len = header_label.length() +
2*(sizeof(AddressSize));


Yes probably, but what would happen if someone assigns a different
header_label ?

i.e.

int main()
{
Foo::header_label = "gm-product-x.x.x";

};

If this is the case you want to wrap header* in a class.

i.e.

class HeaderStuff
{
std::string header_label;
size_t header_len;
public:
template <int N>
inline HeaderStuff( const char ( & str )[N] )
: header_label( str ),
header_len( N - 1 + 2*(sizeof(AddressType)) )
{
}

operator const std::string & () const
{
return header_label;
}

int length() const
{
return header_len;
}

};


struct Foo
{
static const HeaderStuff m_header_stuff;
....

or simply compute it every time:


class HeaderStuff
{
std::string header_label;

inline HeaderStuff( const char * str )
: header_label( str )
{
}

operator const std::string & () const
{
return header_label;
}

int length() const
{
return header_label.length() + 2*(sizeof(AddressType));
}

};
 
L

Luther Baker

Gianni Mariani wrote:
....
Yes probably, but what would happen if someone assigns a different
header_label ?

i.e.

int main()
{
Foo::header_label = "gm-product-x.x.x";

};

The header_label will be private so the application can't change it, but
it is possible a class/instance method might accidentally change it ....
so at the very least, I should make it const.

Additionally, your point is well taken, I see no reason why I can't
encapsulate the entire header into a separate class.

Thanks,

-Luther
 
L

Luther Baker

Bob Hairgrove wrote:

....
The C++ Standard articles which specify this are as follows:

<quote>
"9.4.2 Static data members
...
7 Static data members are initialized and destroyed exactly like
non-local objects. (3.6.2, 3.6.3)"
</quote>

Since 3.6.2 and 3.6.3 are rather lengthy, I'll leave the rest up to
you to find out by referring to the Standard.

In short, static objects initialized with a constant expression (or
zero-initialized) are done before any static objects initialized by
dynamic initialization (e.g. by a function call). Dynamically
initialized objects are initialized "in the order in which their
definition appears in the translation unit". IOW, this is different
than member data which is initialized in the order of the
*declaration* of the members.

Thanks for the direction Bob - let me see if I understand this:

In 3.6.2, objects with static storage duration with dynamic
initialization seem to be elaborated on, but the specifics of
initialization order regarding non-POD types (std::string), *static*
storage duration and *static* initialization seem to be avoided ... and
possibly circular (one section refers to another).

3.6.2p1 ends

"The initialization of local static objects is described in 6.7."

6.7p4 ...

"An implementation is permitted to perform early initialization of other
local objects with static storage duration under the same conditions
that an implementation is permitted to statically initialize an object
with static storage duration in namespace scope (3.6.2)."

So, it looks like ... implementation defined.
Most compilers have proprietary means of ensuring that certain global
initializations are done before anything else, usually involving some
#pragma expression. E.g. in Borland C++ Builder, it's "#pragma
startup(<some number>)", M$VC++ has "#pragma compile" or something
similar.

Therefore, the linkage order, and perhaps the compiler options, will
also have an influence on the order in which static objects are
created and destroyed.

Thanks for the insight. I believe I will follow Gianni's suggestion and
encapsulate the header into its own class.

-Luther
 

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

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,682
Members
48,796
Latest member
Greg L.

Latest Threads

Top