2
votes

So I'm building a syntax compiler with ANTLR and some of the generated code looks like this:

const int ExampleClass::EXAMPLEVAR = OtherExample::OTHEREXAMPLEVAR;

As you can see this fits the "static initialization order fiasco" description.

The problem is that one of the goals of this project is that the generated C++ code can be used as a base for further syntax compilation as easily as possible.

That's why the "construct on first use" paradigm might be a problem in this case: It would be much harder to differentiate between a static variable or a static function.

Now I have read on several occasions that the problem doesn't exist if these static variables are initialized in a single compilation unit.

So I have this idea of moving all these conflicting situations in a separate .cpp file ordered by their dependencies.

The generated code for these conflicting situations would look like this:

//StaticInitializations.cpp
#include "ExampleClass.h"
#include "OtherExample.h"
const int OtherExample::OTHEREXAMPLEVAR = 3; 
const int ExampleClass::CHANNEL_TYPE_TV = OtherExample::OTHEREXAMPLEVAR;

My question is: would this work?

1
There's a [static-order-fiasco] tag? Wow.NPE
Why wouldn't that work? It should.Pubby
The technical question: Yes, within a single compilation unit all objects are initialized in the order they appear. The other question is: Will you be able to maintain this?Bo Persson
@BoPersson Well, I was planning on generating a compiler warning as well. It's an architectural problem and the purpose of this approach is just to generate working code. It should be up to the people who use it to alter the architecture so these constructs disappear.Moonsurfer_1
@Pubby I wasn't sure if it would work because of the response of DrawnOnWard on this question: stackoverflow.com/questions/3035422/… . If compilers like gcc really initialize static vars lazily, then this approach won't do at all.Moonsurfer_1

1 Answers

7
votes

So I have this idea of moving all these conflicting situations in a separate .cpp file ordered by their dependencies.

That would be a file that you need to update for code in other parts, and a dependency in your code that you need to track and keep up to date manually (a source of bugs basically).

Don't do that.

The order of static initializations can be forced, by using static functions instead:

/* static */
int ExampleClass::EXAMPLEVAR()
{
    static const int value = OtherExample::OTHEREXAMPLEVAR();
    return value;
}

This guarantees that the values will be returned/initialized respecting initialization order dependencies.