0

嗨,在这个问题中,我读到编译顺序无关紧要,但我的情况很奇怪。

我在 CCSizePolicy.cpp 文件中有几个全局变量它们看起来像这样:

const CCSizePolicy CCSizePolicyWrapContent ( Const::WRAP_CONTENT );
const CCSizePolicy CCSizePolicyMatchContent ( Const::MATCH_PARENT );
const CCSizePolicy CCSizePolicyZero ( Policy::SP, 0 );

在标题中

    enum Const
    {
        WRAP_CONTENT = -1, MATCH_PARENT = -2
    };

extern const CCSizePolicy CCSizePolicyWrapContent;
extern const CCSizePolicy CCSizePolicyMatchContent;
extern const CCSizePolicy CCSizePolicyZero;

同样在 CCLayoutParams.h

extern const CCLayoutParams CCLayoutParamsMatchMatch;
extern const CCLayoutParams CCLayoutParamsWrapWrap;
extern const CCLayoutParams CCLayoutParamsMatchWrap;
extern const CCLayoutParams CCLayoutParamsWrapMatch;

和 CCLayoutParams.cpp

const CCLayoutParams CCLayoutParamsMatchMatch ( CCSizePolicyMatchContent,
        CCSizePolicyMatchContent );

const CCLayoutParams CCLayoutParamsWrapWrap ( CCSizePolicyWrapContent,
        CCSizePolicyWrapContent );

const CCLayoutParams CCLayoutParamsMatchWrap ( CCSizePolicyMatchContent,
        CCSizePolicyWrapContent );

const CCLayoutParams CCLayoutParamsWrapMatch ( CCSizePolicyWrapContent,
        CCSizePolicyMatchContent );

所以当我在我的程序中使用它们时,我调用 CCLayoutParamsWrapWrap.getWidth() 和 CCLayoutParamsWrapWrap.getHeight()

这应该输出我 -1 -1 但我有 0 0 ...

makefile 中的顺序如下所示:

src/view/layout/CCLayoutParams.cpp\
...
src/view/CCSizePolicy.cpp\

当我将其更改为

src/view/CCSizePolicy.cpp\
src/view/layout/CCLayoutParams.cpp\
...

一切都开始工作(我得到-1 -1)这是怎么回事?

我使用 gcc 版本 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) 的 Linux

我的整个项目都被窃听了,我不知道为什么,因为我按名称对源文件进行排序???!?!

4

2 回答 2

2

未指定不同源文件中全局变量的初始化顺序。因此,它可以依赖于任何东西,包括例如文件编译的顺序。

在这种情况下,如果CCLayoutParamsWrapWrap在 之前初始化CCSizePolicyWrapContent,那么它的构造函数将看不到 的-1构造函数设置的值CCSizePolicyWrapContent。相反,它将看到0由所谓的“静态初始化”设置的值,这发生在“动态初始化”(即构造函数调用)之前。

我不知道 gcc 具体是什么导致了差异,但我怀疑真正重要的是链接顺序而不是编译顺序。不过,这只是一个猜测,如果您想确认或反驳它,您可以进行测试。重要的一点是你不应该依赖它,因为它不需要那样做。

在 C++11 中,我认为你可以通过确保它CCSizePolicyWrapContent是一个带有构造函数的constexpr对象来解决这个问题。constexpr否则,您应该阅读“静态初始化顺序惨败”,以及可用于对初始化顺序施加约束的各种技术,然后选择适合您情况的一种。

于 2013-07-20T20:34:13.617 回答
2

最有可能的不是文件的编译顺序,而是文件的链接顺序(我希望这是由你的源代码的顺序定义的) - g++ 在链接阶段“收集”变量的全局初始化,然后按照它们被发现的顺序处理它们。然而,这恰好是“观察到的行为”。C++ 中不同编译单元之间的初始化是未定义的。你不能依赖它以一种或另一种方式,绝对没有什么可以阻止 g++ 改变它放置全局初始化的顺序,以便它以相反的顺序而不是当前顺序完成(因为这使得链接过程更快,或其他一些聪明的理由——或者只是“觉得喜欢”)——他们甚至不必告诉你他们已经这样做了。

因此,基本上,如果您有全局对象,那么您必须将它们放入单个源文件(“globalobjects.cpp”或类似的)以使它们以定义的顺序初始化,或者不依赖于之前被初始化的对象其他。或者依赖于“只要我将文件以正确的顺序放置在正确的顺序”的模糊定义。

于 2013-07-20T20:40:27.233 回答