0

Consider the following code:

class Foo {
public:
    static const char one[];
    static const char two[];
    static const char* all[];
};

const char Foo::one[] = "one";
const char Foo::two[] = "two";
const char* Foo::all[] = {Foo::one, Foo::two};

int main()
{
    for (const auto& x: Foo::all) {
        std::cout << x << std::endl;
    }
    return 0;
}

If works as expected, but I am using static variables (one and two) to initialize another static variable. Can I run into static initialization order fiasco here?

I can also add constexpr to all declarations and move initialization to declaration:

class Foo {
public:
    static const constexpr char one[] = "one";
    static const constexpr char two[] = "two";
    static const constexpr char* all[] = {one, two};
};

Will it change anything with respect to static initialization order fiasco?

Petr
  • 9,812
  • 1
  • 28
  • 52

2 Answers2

1

Inside one TU, order of initialization is specified (top to bottom), so you don't have issue.

And even if split in different TU, you don't read values, so it would be ok too. (it would be for const std::string Foo::all[] = {Foo::one, Foo::two} for example).

Jarod42
  • 203,559
  • 14
  • 181
  • 302
  • I'm not reading values of chars, but I'm reading values of pointers (as `Foo::one` is a pointer), am not I? – Petr Feb 21 '19 at 15:20
  • `Foo::one` is an array (of 4 char), not a pointer. So you don't initialize the pointer, but the content. If you had `static const char* one`, then yes, your `all[0]` might be `nullptr` or `"one"` (assuming differents TU) – Jarod42 Feb 21 '19 at 15:43
1

No, there is no fiasco here. The order of static variable initialization within one translation unit is defined, and it is in the order of their definitions.

Making it a constexpr will change a couple of things, but not the initialization ordering.

SergeyA
  • 61,605
  • 5
  • 78
  • 137