Reputation: 2041
I have a C++ program with three source files:
// main.cpp
auto return_value = managed_call(int value);
// managed.cpp
#include "private_impl.hpp"
int managed_call(int arg) {
if (arg == 0)
return private_func();
else
return arg;
}
//private_impl.cpp
static some_type some_var = construct_static_object_might_blow();
int private_func() {
....
return 42;
}
My question is about the initialization of the static object in private_impl.cpp
: "when does that take place?" or more specifically - is it only initialized if the private_func
function is called?
I actually simplified the example a bit too much; the code in question will be run as a Python extension - i.e. it is dlopen()
which is the crucial init step. This SO question turned out to be spot on.
Upvotes: 2
Views: 333
Reputation: 1737
Non-local static variables are initialized when their compilation unit is initialized. The standard demands that a compilation unit is initialized no later than when an element from it is accessed first, so in your example construct_static_object_might_blow()
will definitely be called before the first call of private_func()
. The compiler may initialize private_impl.cpp
's translation unit before calling main()
, but this is nothing you should rely on.
Upvotes: 1
Reputation: 238401
When is the static init called in C++
I suppose that you mean, when is the variable with static storage duration initialised. If the variable has static initialisation, that happens before anything else.
If the variable has dynamic initialisation, then it is initially zero initialised during the static initialisation. The exact point of dynamic initialisation is implementation defined. The variable will be initialised at some point before it - or any other variable from that translation unit (TU) - is accessed the first time, or before any function from that TU is called.
is it only initialized if the private_func function is called?
It may be initialised whether private_func
is called or not. But if private_func
is called, then the variable will be initialised at some point before the function call. It is unclear to me whether the initialisation can be deferred so far that it never happens.
Relevant standard quotes in this SO post.
Upvotes: 3
Reputation: 39
A way to get by the static init, is by making a late init of the object.
Something like this
class some_class
{
public:
some_class() {} // do nothing
~some_class() {} // do nothing either
void set(some_type value) { val = value; }
some_type get() { return val; }
void shutDown { // do some cleanup }
private:
some_type val;
}
static some_class g_SomeClass ;
int main()
{
g_SomeClass.set("something");
g_SomeClass.shutDown();
return 0;
}
If your class need a proper way to shutdown, then you must do that by calling the shutdown. Could that be a solution ?
Upvotes: 0
Reputation: 31459
You have no guarantee about the order that static global objects are initialized in across compilation units. See https://isocpp.org/wiki/faq/ctors#static-init-order - you do have guarantees within a translation unit though.
The best way to not get bitten by this is to not have globals (singletons) in the first place.
Upvotes: 2