是否可以将隐式函数作为函数指针传递给C?

时间:2013-02-23 19:32:12

标签: c function-pointers

最近我发现可以通过在函数调用中将其转换为函数来将隐式数组传递给函数

void foo(int* array);
foo((int[4]) {1,2,3,4});

但是,我想知道在将函数指针传递给函数时是否可以执行相同的操作,所以类似于:

void bar(void (*foobar)(void));
bar((void) {printf("foobar\n");});

那么甚至可以这样做吗?

我想知道的原因是,如果我有一大块代码可能具有某种循环结构,但核心功能在实例之间发生变化,我不想让我的代码丢失多个临时函数只是将它们传递给另一个函数。因此,希望能够在参数中定义临时函数。

非常感谢

3 个答案:

答案 0 :(得分:5)

不,不是标准C.你有两个非标准替代品:

一。 GCC的“嵌套函数”扩展(仅限GCC):

void call(void (*fn)())
{
    fn();
}

void somefunc()
{
    void tmp_func()
    {
        printf("Hello world!\n");
    }
    call(tmp_func);
}

二,Apple的区块(最近的GCC和Clang):

void call(void (^blk)())
{
    blk();
}

call(^{
    printf("Hello world!\n");
});

答案 1 :(得分:1)

“隐式数组”实际上是compound literal,它是C99特定的。

另一方面,使用标准C无法实现匿名函数。如果使用GNU GCC,可以使用两个扩展模仿它们:

  1. Nested Functions
  2. Statement expressions
  3. 首先创建一个包装器宏:

    #define lambda(return_type, body)     \
    ({                                    \
        return_type lambda_function body; \
        lambda_function;                  \
    })
    

    然后你可以像这样使用它

    bar(lambda(void, (void)
        {
            printf("foobar\n");
        })
    );
    

答案 2 :(得分:0)

您正在寻找的功能不是C标准的一部分。但是,这正是阻止(标准的Apple扩展)的问题(或其中一个问题),旨在解决问题。如果您正在为OS X 10.5或更高版本(或在其他支持的平台上使用带有块运行时的clang进行编译;请参阅mackyle/blocksruntime),您可以将代码更改为:

void bar(void (^foobar)(void));

并像这样调用:

bar(^{
    printf("foobar\n");
});