全球化与炼金术打破?

时间:2010-11-12 23:17:55

标签: flash alchemy

似乎Adobe Alchemy没有运行全局构造函数。这是一些简单的测试代码:

#include <stdio.h>

class TestClass {
public:
    TestClass(const char message[]) {
        printf("hello %s \n", message);
    }
};

TestClass global("global");

int main(int argc, char **argv) {
    TestClass local("local");
    printf("in main\n");
    return 0;
}

使用原生gcc编译时,输出:

hello global
hello local
in main

使用alchemy gcc编译时,输出:

hello local
in main

这个问题打破了很多代码,特别是UnitTest++(这取决于全局变量被初始化以使其自动测试列表功能正常工作)。

我真的想深究这一点。它是一个错误还是一个功能,并没有及时实现发布?可以解决吗?

编辑:Adobe论坛上的相关帖子为here

1 个答案:

答案 0 :(得分:2)

我遇到了同样的问题。据我所知,情况似乎如此:

如果一个类在初始化期间的任何时候尝试动态分配,那么类类型的每个静态和全局变量都将无法初始化。可能这是因为ByteBuffer用于动态内存尚不可用。我希望Alchemy能够更清楚地了解它的错误信息,因为此刻它就像一堆旧的圣诞灯,其中一个死灯泡会导致整条线关闭。

对于变通方法,一旦发现了违规对象,就需要以某种方式将其初始化推迟到运行时。想到的三种技术是指针,惰性求值函数或对使用placement new初始化的缓冲区的引用。

指针

// `global` is now a pointer
TestClass *global;

// all global variable initialization is found here now
void init_globals() {
  global = new TestClass("global");
}

int main(int argc, char **argv) {
  // this needs to be explicitly called at the start Alchemy
  init_globals();

然后,您需要重构代码,将global的每次出现都更改为(*global)

功能

// `global` is now a function
TestClass& global() {
  // static locals are initialized when their functions are first called
  static TestClass global_("global");
  return global_;
}

现在您需要用global替换global()的每个出现。值得注意的是,这是这三种技术中唯一不需要显式init_globals调用的技术。我推荐这种方式,除非由于某种原因改名为global()的名称很麻烦......在这种情况下:

安置新

// a memory buffer is created large enough to hold a TestClass object
unsigned char global_mem[sizeof(TestClass)];
// `global` is now a reference.  
TestClass& global = *(TestClass*)(void*)global_mem;

void init_globals() {
  // this initializes a new TestClass object inside our memory buffer
  new (global_mem) TestClass("global");
}

int main(int argc, char **argv) {
  init_globals();

此方法的优点是您无需更改任何其他代码,因为global仍称为global。不幸的是,保持init_globals功能可能很麻烦。


修改:
正如在后面的问题中发现的那样,除了动态分配之外,在Alchemy初始化期间也无法调用包含静态局部变量的函数。