为了教育目的我正在写一本特兰斯佩勒。我的播音器从我的语言到C语言。
我现在正在编写闭包语法分析器和代码生成组件。
我看到人们说,C++中的闭包实际上被转换为未命名的结构类型,其中捕获的值作为变量。
这个代码
int c = 10;
auto closure = [=] () -> void {
std::cout << c << std::endl;
};转化成这样的东西--基本上是在引擎盖下面,所以他们说。
struct UNNAMED_TYPE_0 {
int c;
void operator() () const {
std::cout << c << std::endl;
}
};
// assume the closure is initialized and variables are assigned如果有人想在闭包执行时改变这个int c,他/她必须将这个变量作为ref [&c] () -> void { /* mutation comes here */}传递。但问题是,如果我们在函数中声明int c并在函数中创建闭包,则如下所示
function<void()> aFunction() {
int c = 10;
auto closure = [&c] () -> void { c = 100; }
return closure;
}
aFunction() ();int c被捕获,但一旦aFunction堆栈被销毁,int c也被销毁。这意味着,如果我们尝试在已释放的地址上写入,我们可能希望运行segmentation fault(core dumped)指针错误。
在Java中,
// suppose this callback interface exists
public interface VoidCallback {
public void method();
}
public void aMethod() {
int c = 10;
VoidCallback callback = () -> c = 10; /* this gives an error */
// local variables referenced from a lambda expression must be final or effectively final
}Java处理这样的闭包,并确保闭包捕获没有任何变化(比如隐式捕获)。这意味着Java传递闭包捕获的是副本,而不是引用。对于引用或类类型,只有对象指针作为副本传递。尽管指针引用不发生变异,但可以对指针指向的对象内的内容进行变异。这基本上和以前的一样。
在Objective-C,中
__block int c = 0;
// they say, this `int c` is allocated in heap instead of stack
// so that it exists until the closure is finished executing.
void (^ closure) (void) = ^void() {
c = 10; // this is valid
// this actually changed the `int c`'s value
}; 在Swift中
var a : Int = 10;
var closure = { [] () -> Void in
a = 10; // this is valid by default
// unless `var a` is declared as `let a`
};因此,这意味着,Objective和Swift将基本捕获列表作为指针分配.这样他们就可以变异了。
P.S:请注意,Swift闭包捕获列表只适用于类或引用类型,但我的意思是在这里隐式捕获基元类型。
,我是
__block int c = 0;
// they say, this `int c` is allocated in heap instead of stack
// so that it exists until the closure is finished executing.
void (^ closure) (void) = ^void() {
c = 10; // this is valid
// this actually changed the `int c`'s value
}; 与(基本上)对此相同
int * c = malloc(sizeof(int));
*c = 0;
void (^ closure) (void) = ^void() {
*c = 10;
if (c) {
free(c);
c = NULL;
}
}; 我认为,一旦完成闭包,释放指针变量就太糟糕了。
如果有大量的闭包指向变量并在执行时发生变异,怎么办?
如果这些闭包在不同线程之间传递或执行怎么办?
我想出了一个使用参考计数技术的解决方案。
当创建一个变异变量的闭包时,该变量将被保留。
当改变变量的闭包被破坏时,变量将被释放。
当没有闭包时,变量将被真正释放。为了确保线程安全,我将锁定和解锁计数器变量地址,因为闭包操作引用计数技术。
如果有别的技术,请指导我。
任何语言的任何解释都是非常感激的。
目前,我对汇编语言一窍不通。
对于主持人来说,由于这个问题是一种研究,我恳请你们不要过于宽泛。
发布于 2018-01-08 09:24:58
以下给我留下的印象是:“我正在为教育目的写一个特兰斯佩勒,我的播音器从我的语言转到C语言。”现在,这意味着您的语言规范定义了它应该如何操作!我们不能告诉你你的语言应该如何运作。
现在,您已经找到了许多选项:
with原语类型的东西,就像您没有确定性析构函数调用一样(您在那里使用with获得了类似的东西,只是为了完整性),所以这没有任何区别。这些语言给您增加了开销,以保证您没有任何悬空的引用(即使您并不真正需要它)。现在,第一件事是决定哪一个最适合您的语言的对象模型。只有到那时,问题才会出现:如何最好地实现它。关于实现,有许多不同的方法。使用引用计数器是一种(虽然是用无锁原子操作实现的),使用链接列表是另一种,或者使用垃圾收集器。
https://stackoverflow.com/questions/48146679
复制相似问题