2013-03-15 41 views
2

所以我建立一个语法编译器ANTLR和一些生成的代码看起来是这样的:静态初始化顺序失败:相同的编译单元?

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

正如你可以看到这符合“静态变量初始化顺序的悲剧”的描述。

问题是,这个项目的目标之一是生成的C++代码可以用作进一步语法编译的基础,尽可能容易。

这就是为什么在这种情况下“首次使用构造”范式可能是一个问题:区分静态变量或静态函数将会困难得多。

现在我已经阅读了几次,如果这些静态变量在单个编译单元中初始化,则问题不存在。

所以我有这种想法将所有这些冲突的情况移动到由它们的依赖关系排序的单独的.cpp文件中。

这些相互矛盾的情况下,生成的代码是这样的:

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

我的问题是:将这项工作?

+6

有'[static-order-fiasco]'标签?哇。 – NPE 2013-03-15 08:36:00

+0

为什么不能这样工作?这应该。 – Pubby 2013-03-15 08:37:22

+0

技术问题:是的,在一个编译单元中,所有对象都按照它们出现的顺序进行初始化。另一个问题是:你能维持这个吗? – 2013-03-15 08:39:51

回答

7

所以我有这种想法将所有这些冲突的情况移动到一个单独的.cpp文件中,这些文件是由它们的依赖项排序的。

这将是一个需要更新其他部分代码的文件,以及需要手动跟踪和保持最新的代码依赖关系(基本上是bug的来源)。

不要这样做。

静态初始化的顺序可以被强制通过使用静态函数来代替:

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

这保证了值将返回/初始化尊重初始化顺序依赖性。

+0

是的,你是对的。我的同事告诉我同样的事情。但是,我假设这些初始化是一个架构问题。因此,我也会发出警告,以便这些结构可以被替换。 我认为这种方法仍然可以作为中介解决方案,所以团队有足够的时间来逐步解决这些问题。 尽管感谢您的回复,但这是一个值得关注的问题;)但正如我在问题中所说的那样:使用生成的代码作为进一步语法编译的基础会更困难。 – 2013-03-15 09:39:57

+0

你知道吗?毕竟它可能是最好的答案。我仍然可以通过用#define常量注释该函数来解决not-easily-identifiable-as-static-var部分。谢谢;)我接受这个答案。 – 2013-03-15 09:48:41