2

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?

Update

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.

Community
  • 1
  • 1
user422005
  • 1,989
  • 16
  • 34
  • 2
    https://isocpp.org/wiki/faq/ctors#static-init-order – Jesper Juhl Nov 26 '19 at 17:25
  • It is likely to be done before any code is executed. That way, the executable does not have to keep track of whether you have already called the function. (before the C tag was removed). – Weather Vane Nov 26 '19 at 17:25
  • [The Bits Between the Bits: How We Get to `main()`](https://www.youtube.com/watch?v=dOfucXtyEsU) – Evg Nov 26 '19 at 17:25
  • 1
    Does this help? [When are static and global variables initialized?](https://stackoverflow.com/questions/17783210/when-are-static-and-global-variables-initialized) – ChrisMM Nov 26 '19 at 17:26
  • I assume `private_func()` uses `some_var`, but you didn't show that. Instead of "...." show an actual [mcve] so that we can answer your question without wasting time guessing. – Lightness Races in Orbit Nov 26 '19 at 19:02

4 Answers4

3

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.

eerorika
  • 232,697
  • 12
  • 197
  • 326
2

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.

Jesper Juhl
  • 30,449
  • 3
  • 47
  • 70
1

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.

ahans
  • 1,697
  • 12
  • 19
0

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 ?

tannic
  • 37
  • 5