在this SO帖子中,Brian Postow suggested一个涉及虚假匿名函数的解决方案:
创建一个comp(L)函数,返回长度为L的数组的comp版本......这样L成为参数,而不是全局
如何实现这样的功能?
答案 0 :(得分:6)
请参阅the answer I just posted该问题。您可以使用callback(3)
库在运行时生成新函数。它不符合标准,因为它涉及许多丑陋的平台特定的黑客攻击,但它确实适用于大量系统。
库负责分配内存,确保内存可执行,并在必要时刷新指令缓存,以确保动态生成的代码(即闭包)是可执行的。它本质上生成的代码存根在x86上看起来像这样:
pop %ecx
push $THUNK
push %ecx
jmp $function
THUNK:
.long $parameter
然后返回第一条指令的地址。这个存根所做的是将返回地址存储到ECX(x86调用约定中的临时寄存器)中,将额外的参数压入堆栈(指向thunk的指针),然后重新推送返回地址。然后,它跳转到实际功能。这导致函数被愚弄,认为它有一个额外的参数,这是闭包的隐藏上下文。
实际上它比那更复杂(在存根末尾调用的实际函数是__vacall_r
,而不是函数本身,而__vacall_r()
处理更多的实现细节),但这是基本原则。
答案 1 :(得分:2)
我不相信你可以用C99做到这一点 - 除非你在运行时手动生成机器代码,否则没有部分应用程序或关闭工具可用。
尽管你需要编译器支持,但Apple最近提出的块才有用。 Here's a brief overview of blocks.我不知道苹果以外的任何供应商何时会支持他们。答案 2 :(得分:1)
在C或C ++中,无法在运行时生成普通函数。 Brian建议的是基于一个很大的“if”:“......如果你能伪造匿名函数......”。而“if”的答案是:不,你不能。 (虽然不清楚“假”是什么意思。)
(在C ++中,可以在运行时生成类似函数的对象,但不能生成普通函数。)
以上内容适用于标准C和C ++语言。特定实现可以支持各种实现提供的扩展和/或手动实现的黑客,例如“闭包”,“代表”和类似的东西。当然,这些都与标准C / C ++语言无关。