5

I'm trying to understand when the static initialization order fiasco is a real problem. If I use a string constant like kName below would it suffer any of the problems of the static initialization order fiasco? Is this a problem in this case because an instance of Derived can be created before kName is initialized as in main.cpp?

// Base.cpp
namespace test {
class Base {
public:
  virtual ~Base() = default;

protected:
  explicit Base(const std::string &name);
};
} // namespace test

// Derived.cpp
namespace test {
static const std::string kName = "my name";

class Derived : public Base {
public:
  Derived() : Base(kName) {}
  ~Derived() override = default;
};
} // namespace test

// main.cpp
int main() {
  test::Derived instance{};
  return 0;
}
Mike Sweeney
  • 1,896
  • 2
  • 18
  • 20
  • static initialization order fiasco happens with depending static variable between several files. – Jarod42 Feb 07 '19 at 08:57
  • So when would it be an actual problem using a string constant? I'm having a hard time wrapping my head around when this can be a problem. If the instance of `test::Derived` were defined outside of `main()` would it be a problem? – Mike Sweeney Feb 07 '19 at 08:58
  • Here you have only one (and so no dependencies). So you are fine. Having a static `Derived` in Base.cpp/main.cpp would be problematic. – Jarod42 Feb 07 '19 at 08:58
  • Maybe [this](http://coliru.stacked-crooked.com/a/37f28ee920b9f281) helps a bit to understand. – user1810087 Feb 07 '19 at 09:26

2 Answers2

2

The main function will not be called until all "global" variables are initialized. That includes static member variables as well as variables in namespace scope (static or not).

So in this case it's no problem since you define the instance inside the main function.

It would be different if the definition of instance was done statically outside the main function.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • Wow, ok. In my example I actually just defined the instance inside `main()` without any thought to give an example. So practically speaking it seems like using static string constants like this can be a bad thing to do since I don't know how people will instantiate the class. I see this kind of use often so I'm surprised. – Mike Sweeney Feb 07 '19 at 09:02
  • 1
    @MikeSweeney SIOF normally only kicks in when more than one file is involved. The order of initialisations *within* a single translation unit is well-defined. The order across translatin units, not so much. – Angew is no longer proud of SO Feb 07 '19 at 09:03
  • Yeah, I'm having a hard time with this because with static objects having internal linkage my mind automatically thinks there can never be more than 1 translation unit involved. – Mike Sweeney Feb 07 '19 at 09:04
2

Within a specific translation unit, the order of initialization of static objects is guaranteed to be the order in which the object definitions appear in that translation unit. The order of destruction is guaranteed to be the reverse of the order of initialization. However, there is no guarantee concerning the order of initialization of static objects across translation units. This is what is termed as static initialization order fiasco.

So here you will not have static initialization order fiasco.

P.W
  • 26,289
  • 6
  • 39
  • 76
  • Your last sentence seems to contradict what "Some programmer dude" said. – Mike Sweeney Feb 07 '19 at 09:06
  • How does it? He said "It would be different if the definition of `instance` was done **statically** outside the main function" But there is no such definition of `instance` outside the `main` function (i.e. in main.cpp). – P.W Feb 07 '19 at 09:08
  • Because what matters seems to be how/where `Derived` is instantiated and not how many static objects there are in the `Derived` class itself. – Mike Sweeney Feb 07 '19 at 09:10
  • @MikeSweeney: I should have said, one static instance rather than one static variable. Anyway, I removed that sentence. – P.W Feb 07 '19 at 09:23