2

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?

PeeHaa
  • 71,436
  • 58
  • 190
  • 262
Moonsurfer_1
  • 105
  • 1
  • 7
  • 6
    There's a `[static-order-fiasco]` tag? Wow. – NPE Mar 15 '13 at 08:36
  • Why wouldn't that work? It should. – Pubby Mar 15 '13 at 08:37
  • 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 Mar 15 '13 at 08:39
  • @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 Mar 15 '13 at 08:48
  • @Pubby I wasn't sure if it would work because of the response of DrawnOnWard on this question: http://stackoverflow.com/questions/3035422/static-initialization-order-fiasco/3035673#3035673 . If compilers like gcc really initialize static vars lazily, then this approach won't do at all. – Moonsurfer_1 Mar 15 '13 at 08:48
  • Also see [AddressSanitizerInitializationOrderFiasco](https://github.com/google/sanitizers/wiki/AddressSanitizerInitializationOrderFiasco). – jww Jan 11 '16 at 10:35

1 Answers1

7

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.

utnapistim
  • 26,809
  • 3
  • 46
  • 82
  • Yes, you're right. My coworkers are telling me the same thing. However, I'm assuming that these kind of initializations are an architectural problem. I would therefore generate a warning as well, so that these kind of constructs can be replaced. I think this approach can still be relevant as an intermediary solution, so the team has enough time to fix these problems incrementally. Thank you for your response though, it is a valid concern ;) But as I said in the question: it would be harder to use the generated code as a base for further syntax compilation. – Moonsurfer_1 Mar 15 '13 at 09:39
  • You know what? It probably is the best answer after all. I can still work around the not-easily-identifiable-as-static-var part by annotating the function with a #define constant. Thank you ;) I'm accepting this answer. – Moonsurfer_1 Mar 15 '13 at 09:48