有没有办法用C来做咖喱饭?

2024-04-20 08:16:52 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我有一个指向函数_stack_push(stack* stk, void* el)的指针。我希望能够调用curry(_stack_push, my_stack),并返回一个只需要void* el的函数。我想不出一个办法,因为C不允许运行时函数定义,但我知道这里有比我聪明得多的人:)。有什么想法吗?


Tags: 函数定义stackmyelpush指向指针
3条回答
<> Laurent Dami发现了一篇论文,讨论C/C++/Objul-C:

中的Currin问题。

More Functional Reusability in C/C++/Objective-c with Curried Functions

对如何在C中实现感兴趣:

Our current implementation uses existing C constructs to add the currying mechanism. This was much easier to do than modifying the compiler, and is sufficient to prove the interest of currying. This approach has two drawbacks, however. First, curried functions cannot be type-checked, and therefore require careful use in order to avoid errors. Second, the curry function cannot know the size of its arguments, and counts them as if they were all of the size of an integer.

本文不包含curry()的实现,但是您可以想象它是如何使用function pointersvariadic functions实现的。

GCC为嵌套函数的定义提供了扩展。虽然这不是ISO标准C,但这可能会引起一些兴趣,因为它能够非常方便地回答问题。简而言之,嵌套函数可以访问父函数局部变量,父函数也可以返回指向它们的指针。

下面是一个简短的、不言而喻的例子:

#include <stdio.h>

typedef int (*two_var_func) (int, int);
typedef int (*one_var_func) (int);

int add_int (int a, int b) {
    return a+b;
}

one_var_func partial (two_var_func f, int a) {
    int g (int b) {
        return f (a, b);
    }
    return g;
}

int main (void) {
    int a = 1;
    int b = 2;
    printf ("%d\n", add_int (a, b));
    printf ("%d\n", partial (add_int, a) (b));
}

然而,这种结构有一个局限性。如果您保留指向结果函数的指针,如

one_var_func u = partial (add_int, a);

函数调用u(0)可能导致意外行为,因为u读取的变量apartial终止后被破坏。

this section of GCC's documentation

这是我第一次发自肺腑的猜测(可能不是最好的解决办法)。

curry函数可以从堆中分配一些内存,并将参数值放入堆分配的内存中。诀窍是让返回的函数知道它应该从堆分配的内存中读取它的参数。如果返回的函数只有一个实例,那么指向这些参数的指针可以存储在singleton/global中。否则,如果返回函数的实例不止一个,那么我认为curry需要在堆分配内存中创建返回函数的每个实例(通过将诸如“获取指向参数的指针”、“推送参数”和“调用另一个函数”之类的操作码写入堆分配内存)。在这种情况下,您需要注意分配的内存是否是可执行的,甚至可能(我不知道)害怕防病毒程序。

相关问题 更多 >