【问题标题】:Emulating lambdas in C?在 C 中模拟 lambda?
【发布时间】:2015-06-08 06:49:38
【问题描述】:

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

有没有我可以做的某种预处理指令,或者一些可以让这个更干净的宏?我受到 Jon Blow 的启发尝试编译器开发,他似乎用他的语言 Jai 实现了 Lambdas。但是,我认为他在生成字节码,然后到 C 中做了一些事情?我不确定。

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

【问题讨论】:

  • 在什么情况下生成 C 代码?使用哪个操作系统和编译器?为什么是 C 而不是更好的东西(Common Lisp 或 Ocaml)?你在实现一些编译器吗?你有垃圾收集器吗?请编辑您的问题以改进它。
  • 项目是什么,它的 URL 是什么?
  • 可惜你的语言没有 GC 或闭包。
  • 是的,我的意思是有可能。我现在只是在胡思乱想,你还有什么关于代码生成到另一种源语言的书可以推荐吗?
  • 我强烈推荐 Queinnec 的 Lisp In Small Pieces(值得学习一点 Scheme,也许只是为了理解那本书)

标签: c lambda code-generation


【解决方案1】:

有几种方法可以做到这一点(在 C 中“使用”lambda)。要理解的重要一点是 lambdas 给出closures 并且闭包将“代码”与“数据”(关闭的值)混合在一起;请注意,对象也将“代码”与“数据”混合在一起,并且对象和闭包之间存在相似性。参见this answerProgrammers

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

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

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

过去有一些lambda.h 头库可以为闭包生成一个特定于机器的trampoline 代码(本质上是生成一个将一些封闭值作为参数推送然后调用一些例程的代码)。您可能会使用一些JIT compilation 技术(使用libjit、GNU lightningLLVMasmjit,...)来做同样的事情。另请参阅 libffi 以调用 任意 函数(仅在 运行时 已知的签名)。

请注意,闭包和garbage collection 之间存在很强但间接的关系(请阅读GC handbook 了解更多信息),每个functional language 都有一个GC 并非偶然。 C++11 lambda 函数是一个例外(很难理解 C++11 闭包的所有内存管理的复杂性)。因此,如果您正在生成 C 代码,您可以并且可能应该使用 Boehm's conservative garbage collector(包装 dlopen)并且您将拥有闭包 GC-ed 值。 (您可以使用其他一些 GC 库,例如 Ravenbrook's MPS 或我未维护的 Qish...)然后您可以约定每个生成的 C 函数都将其闭包作为第一个参数。

我建议阅读Scott's book on Programming Language Pragmatics 和(假设您了解一点Scheme 或Lisp;如果您不了解Scheme 并阅读SICPQueinnec's book Lisp In Small Pieces(如果您碰巧读法文,读最新法文variant)。

【讨论】:

  • @user3839220:但是,请编辑您的问题以改进它。我很好奇您在做什么,为什么要问,以及如何生成 C 代码?你的项目是免费软件吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-02
  • 1970-01-01
相关资源
最近更新 更多