0

Is it true that in the following code, which I took from another question, in accordance with the standard, static member variable w should be initialized dynamically?

// MyClass.h:
class MyClass
{
public:
    static int z; 
};

// MyClass.cpp:
int MyClass::z = 4;

// MyOtherClass.h:
class MyOtherClass
{
public:
    static int w;
};

// MyOtherClass.cpp:
int MyOtherClass::w = MyClass::z;

I disagree with the accepted answer, because according to this standard's wording:

An implementation is permitted to perform the initialization of a non-local variable with static storage duration as a static initialization even if such initialization is not required to be done statically, provided that ...

— the static version of the initialization produces the same value in the initialized variable as would be produced by the dynamic initialization if all variables not required to be initialized statically were initialized dynamically.

But how can the compiler possibly know what value will be produced by initialization of z if its definition is unreachable from MyOtherClass.cpp? If it can't know, then the condition can't be satisfied, then the only standard way to initialize w is dynamic. Is it right and the answer to the other question is wrong?

Oleksa
  • 635
  • 5
  • 15
  • 1
    It could do link-time optimization or similar – M.M Jul 02 '21 at 13:18
  • 2
    If `w` and `z` is something more complex then Static Initialization Order Fiasco may accrue. With simple `int` type linker should be able to resolve this. I would define a seperate `constexpr` and use for both fields. – Marek R Jul 02 '21 at 13:19
  • If anything, that second paragraph you quoted is redundant as it doesn't say anything that isn't already covered by the as-if rule. –  Jul 02 '21 at 13:28
  • Since `z` and `w` are in different translation units, another translation unit may have a static initializer that modifies `z`, making the initialization of `w` uncertain at compile time and something that could vary from compile to compile because the order of initialization is arbitrary (by the linker & loader). – Eljay Jul 02 '21 at 13:38
  • What exactly are you disagreeing with? There doesn't seem to be any grounds for disagreement. Even if the compiler cannot possibly perform static initialisation, it is still allowed to. – n. m. could be an AI Jul 02 '21 at 14:26
  • @n. 1.8e9-where's-my-share m. I think `w` should be `4` either way. It can't be `0` after static initialization because that would be contrary to _"the static version of the initialization produces the same value in the initialized variable as would be produced by the dynamic initialization if all variables not required to be initialized statically were initialized dynamically"_. `z` is required to be initialized statically, so dynamic init of `w`, which comes after static, should use `z` already initialized to `4`, and this result should be the same for static initialization of `w`. – Oleksa Jul 02 '21 at 16:13

0 Answers0