在C中模拟lambdas?

我应该提一下,我在C中生成代码,而不是手动执行此操作。 我这样说是因为如果背后有很多代码并不重要,因为编译器应该管理它。 无论如何,我如何在C中模拟lambda? 我以为我可以在源代码中的某处生成一个带有随机名称的函数然后调用它? 我不太确定。 我还没有真正尝试过任何东西,因为我想在实现它之前把想法弄清楚。

是否有某种预处理器指令可以做,或者某些宏可以使这个更清洁? 我受到了Jon Blow的启发,尝试编译器开发,他似乎用他的语言Jai实现了Lambdas。 但是,我认为他做了一些他生成字节码然后进入C的东西? 我不确定。

编辑:我正在编写一个编译器,编译器只是我的一个项目让我忙碌,而且我想了解更多有关编译器的知识。 我主要使用clang,我使用的是Ubuntu 14.10。 我没有任何垃圾收集,但我想尝试使用某种智能指针-y / rust / ARC启发的内存模型来进行垃圾收集,即几乎没有开销。 我选择C是因为我想更多地涉足它。 我的项目是免费软件,只是一个爱好项目。

有几种方法可以做到这一点(在C中“有”lambdas)。 要理解的重要一点是,lambdas提供闭包 ,闭包是将“代码”与“数据”(封闭值)混合在一起; 请注意,对象也在混合“代码”和“数据”,并且对象和闭包之间存在相似性。 另见程序员的 这个答案 。

传统上,在C中,您不仅使用函数指针,而且还采用了有关回调的约定 。 例如GTK就是这种情况:每次传递一个函数指针时,你也会传递一些数据。 您可以查看回调(给出带有一些void*数据的C函数指针的约定 )作为实现闭包的方法。

既然你生成C代码(这是一个明智的想法,我在MELT中做类似的事情 – 在Linux上运行时生成C ++代码,将其编译成共享对象,并且dlopen -s)你可以采用回调约定并将一些闭合值传递给您生成的每个函数。

您也可以将闭合值视为static变量,但这种方法通常是不明智的。

过去有一些lambda.h头文件库为闭包生成一个特定于机器的trampoline代码(实质上是生成一个代码,它将一些封闭的值作为参数推送然后调用一些例程)。 您可以使用一些JIT编译技术(使用libjit ,GNU lightning , LLVM , asmjit ,….)来执行相同的操作。 另请参见libffi以调用任意函数(仅在运行时已知的签名)。

请注意,闭包和垃圾收集之间存在强烈但间接的关系(请阅读GC手册了解更多信息),并且每种function语言都有GC,这并非偶然。 C ++ 11 lambda函数是一个例外(并且很难理解C ++ 11闭包的所有复杂的内存管理)。 因此,如果您正在生成C代码,您可以并且可能应该使用Boehm的保守垃圾收集器 (包装dlopen )并且您将拥有关闭GC-ed值。 (您可以使用其他一些GC库,例如Ravenbrook的MPS或我未维护的Qish ……)然后您可以使用每个生成的C函数将其闭包作为第一个参数的约定。

我建议阅读Scott关于编程语言语用学的书和(假设你知道一点点Scheme或Lisp;如果你不知道你应该学习一点Scheme并阅读SICP ) Queinnec的书Lisp In Small Pieces (如果你发生的话)阅读法语,阅读最新的法语变体 )。