关闭C - 这有用吗?

时间:2014-06-14 07:56:05

标签: c closures

我开始学习函数式编程,并希望看看我是否可以使用C语言中的闭包。为了从Wikipedia - Closures重现第一个示例,我编写了以下代码:

#include <stdio.h>

void closure (int(** f)(int), int *x) {
    int fcn(int y) {
        return *x + y;
    };
    *f = fcn;
}

int main()
{
    int x = 1;
    int(* f)(int);

    closure(&f, &x);

    printf("%d", f(2));

    return 0;
}

它被编译(gcc 4.8.2。在Ubuntu 14.04。)并且它有效,它打印出3.由于缺乏我在C的专业知识(只有大学的基础课程),我的问题是,是否有一些认真的事情这段代码有问题吗?我被教导功能定义应该是全局的,我从来没有想过这会起作用......

编辑: 当我改变主要功能时,为什么呢?

int main()
{
    int x = 1;
    int(* f)(int);

    closure(&f, &x);

    printf("%d", f(2));
    printf("%d", f(3)); // the only difference

    return 0;
}

我收到Segmentation故障?

2 个答案:

答案 0 :(得分:4)

您的代码有效,因为gcc具有支持嵌套函数的语言扩展名。

但是,在标准C中,您无法在另一个函数中定义函数。

Gnu Nested Functions

  

如果你试图在包含函数退出后通过其地址调用嵌套函数,那么所有的地狱都会破裂。如果您尝试在包含范围级别退出后调用它,并且如果它引用了一些不再在范围内的变量,您可能会很幸运,但冒风险并不明智。但是,如果嵌套函数没有引用超出范围的任何内容,那么您应该是安全的。

答案 1 :(得分:2)

首先,您的程序调用未定义的行为。这是因为函数fcn中定义的函数closure是本地函数。 fcn返回后closure不再存在。所以printf来电

printf("%d", f(2));

通过调用f(2)来调用未定义的行为,因为f指向不在范围内的函数fcn

C语言没有闭包,因为C中的函数不是第一类对象。这意味着函数不能传递给其他函数或者不能从函数返回。实际传递或返回的是指向它的指针。

请注意,嵌套函数和闭包之间存在差异。您看到的是nested function的GCC扩展程序。它不是C标准的一部分。