I use C++ in Visual Studio 2015 sp3. By
#pragma init_seg(compiler)
, I initialize some static variables first(to memory management). https://msdn.microsoft.com/en-us/library/7977wcck.aspx
But, there is
#pragma init_seg(compiler)
in wcerr.cpp(Microsoft Visual Studio 14.0\VC\crt\src\stl\wcerr.cpp), so these objects are initialized before my objects.
Can I compel my object to be initialized first before wcerr.cpp
objects by any compile / link options?
When static keyword is used, variable or data members or functions can not be modified again. It is allocated for the lifetime of program.
If you declare a static variable in a class, if you haven't initialized it, just like with instance variables compiler initializes these with default values in the default constructor. Yes, you can also initialize these values using the constructor.
Within a single compilation unit, static variables are initialized in the same order as they are defined in the source (this is called Ordered Dynamic Initialization). Across compilation units, however, the order is undefined: you don't know if a static variable defined in a.
In C, static variables can only be initialized using constant literals. For example, following program fails in compilation. If we change the program to following, then it works without any error.
One of solutions is to try wrap your static variables to static functions:
static type& My_static_obj() {
static type my_static_obj_;
return my_static_obj_;
}
It looks like a simple type of Singleton and calls Construct On First Use Idiom. Due to standard (C++11 and above) it guaranteed to be initialized once (and even atomically!), and inside its c-tor such an object can access to other "static" variables, so, if there aren't circular dependencies between variables, the order of initialization will be strictly defined.
For additional information see this question and other descriptions of this Construct On First Use Idiom.
Probably the nifty counter idiom can help you somehow in this case:
Ensure a non-local static object is initialized before its first use and destroyed only after last use of the object.
Its motivation is pretty clear:
When static objects use other static objects, the initialization problem becomes more complex. A static object must be initialized before its use if it has non-trivial initialization. Initialization order of static objects across compilation units is not well-defined. Multiple static objects, spread across multiple compilation units, might be using a single static object. Therefore, it must be initialized before use. One example is std::cout, which is typically used by a number of other static objects.
It's worth it to copy and paste directly the example from the above linked page:
Stream.h
#ifndef STREAM_H
#define STREAM_H
struct Stream {
Stream ();
~Stream ();
};
extern Stream& stream; // global stream object
static struct StreamInitializer {
StreamInitializer ();
~StreamInitializer ();
} streamInitializer; // static initializer for every translation unit
#endif // STREAM_H
Stream.cpp
#include "Stream.h"
#include <new> // placement new
#include <type_traits> // aligned_storage
static int nifty_counter; // zero initialized at load time
static typename std::aligned_storage<sizeof (Stream), alignof (Stream)>::type
stream_buf; // memory for the stream object
Stream& stream = reinterpret_cast<Stream&> (stream_buf);
Stream::Stream ()
{
// initialize things
}
Stream::~Stream ()
{
// clean-up
}
StreamInitializer::StreamInitializer ()
{
if (nifty_counter++ == 0) new (&stream) Stream (); // placement new
}
StreamInitializer::~StreamInitializer ()
{
if (--nifty_counter == 0) (&stream)->~Stream ();
}
The header file of the Stream class must be included before any member function can be called on the Stream object. An instance of the StreamInitializer class is included in each compilation unit. Any use of the Stream object follows the inclusion of the header, which ensures that the constructor of the initializer object is called before the Stream object is used.
See the link above for further details.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With