C中的假匿名函数

在这个SO线程中, Brian Postow 提出了一个涉及虚假匿名函数的解决方案:

制作一个comp(L)函数,返回长度为L的数组的comp版本……这样L成为参数,而不是全局

我该如何实现这样的function?

请参阅我刚刚发布到该问题的答案 。 您可以使用callback(3)库在运行时生成新函数。 它不符合标准,因为它涉及许多丑陋的平台特定的黑客攻击,但它确实适用于大量系统。

该库负责分配内存,确保内存可执行,并在必要时刷新指令缓存,以确保动态生成的代码(即闭包)是可执行的。 它本质上生成的代码存根可能在x86上看起来像这样:

  pop %ecx push $THUNK push %ecx jmp $function THUNK: .long $parameter 

然后返回第一条指令的地址。 这个存根所做的是将返回地址存储到ECX(x86调用约定中的临时寄存器)中,将额外的参数压入堆栈(指向thunk的指针),然后重新推送返回地址。 然后,它跳转到实际function。 这导致函数被愚弄,认为它有一个额外的参数,这是闭包的隐藏上下文。

它实际上比那更复杂(在存根末尾调用的实际函数是__vacall_r ,而不是函数本身,而__vacall_r()处理更多的实现细节),但这是基本原则。

我不相信你能用C99做到这一点 – 除非你在运行时手动生成机器代码,否则没有部分应用程序或关闭工具可用。

尽管你需要编译器支持,Apple最近提出的块也可以使用。 这是块的简要概述。 我不知道苹果以外的任何供应商何时会支持他们。

在C或C ++中,无法在运行时生成普通函数。 Brian建议的是基于一个很大的“if”:“……如果你能伪造匿名函数……”。 而“if”的答案是:不,你不能。 (虽然不清楚“假”的含义是什么。)

(在C ++中,可以在运行时生成类似函数的对象,但不能生成普通函数。)

以上内容适用于标准C和C ++语言。 特定实现可以支持各种实现提供的扩展和/或手动实现的黑客,例如“闭包”,“代表”和类似的东西。 当然,这些都与标准C / C ++语言无关。