全局变量被炼金术打破了?
似乎 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 论坛上的相关帖子位于此处。
It seems that Adobe Alchemy isn't running global constructors. Here's some simple test code:
#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;
}
When compiled with native gcc it outputs:
hello global
hello local
in main
When compiled with alchemy gcc it outputs:
hello local
in main
This problem breaks lots of code, notably UnitTest++ (which depends on globals getting initialized to make its auto test-list functionality work).
I'd really like to get to the bottom of this. Is it a bug or a feature that just didn't get implemented in time for the release? Is it possible to workaround?
EDIT: A relevant post on the Adobe Forums is here.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我遇到了同样的问题。据我所知,情况似乎是这样:
如果即使是单个类在初始化期间的任何时候尝试动态分配,类类型的每个静态和全局变量都将默默地无法初始化。 大概这是因为用于动态内存的 ByteBuffer 尚不可用。我希望 Alchemy 的错误消息能够更加清晰,因为目前它就像一串老式的圣诞灯,其中一个坏灯泡会导致整串灯关闭。
对于解决方法,一旦发现有问题的对象,您需要以某种方式将其初始化推迟到运行时。我想到的三种技术是指针、惰性求值函数或对通过放置 new 初始化的缓冲区的引用。
指针
然后,您需要重构代码,将每次出现的
global
更改为(*global)
。函数
现在您需要将每次出现的
global
替换为global()
。值得注意的是,这是这三种技术中唯一不需要显式init_globals
调用的技术。我推荐这种方式,除非名称更改为global()
由于某种原因很麻烦...在这种情况下:Placement new
这种方法的优点是您不需要需要更改任何其他代码,因为
global
仍然只是称为global
。不幸的是,维护init_globals
函数可能很麻烦。编辑:
正如在后面的问题中发现的,除了动态分配之外,在 Alchemy 初始化期间也无法调用包含静态局部变量的函数。
I've run into the same problem. As far as I could tell, this seems to be the case:
Every single static and global variable of class type will silently fail to be initialized if even a single class attempts dynamic allocation at any point during its initialization. Presumably this is because the ByteBuffer being used for dynamic memory isn't yet available. I wish Alchemy would be more clear with its error messages, because at the moment it's like a strand of old-timey Christmas lights where one dead bulb would cause the entire strand to shut off.
For a workaround, once you've discovered the offending object, you'll need to somehow defer its initialization to runtime. The three techniques that come to mind are pointers, lazy evaluation functions, or references to buffers initialized with placement new.
Pointers
You'll then need to refactor your code, changing every occurence of
global
to(*global)
.Function
Now you need to replace every occurence of
global
withglobal()
. Notably, this is the only one of these three techniques that doesn't require an explicitinit_globals
call. I recommend this way unless the name changing toglobal()
is troublesome for some reason... in which case:Placement new
The advantage of this approach is you don't need to change any other code, as
global
is still just calledglobal
. Unfortunately, maintaining aninit_globals
function can be troublesome.Edit:
As discovered in a later question, in addition to dynamic allocation, functions containing static locals also cannot be called during Alchemy's initialization.