这个C代码怎么能有lambda

man*_*ale 5 c lambda

这段代码:

#include <stdio.h>

int main()
{
    void (^a)(void) = ^ void () { printf("test"); } ;
    a();
}
Run Code Online (Sandbox Code Playgroud)

使用clang -Weverything -pedantic -std = c89(版本clang-800.0.42.1)编译时无需警告并打印test.

我找不到有关lambda的标准C的任何信息,gcc也有自己的lambda语法,如果存在标准解决方案,他们会这样做很奇怪.

ali*_*oar 6

C 标准根本没有定义 lambda,但实现可以添加扩展。

Gcc 还添加了一个扩展,以便支持具有静态作用域的 lambda 的编程语言能够轻松地将它们转换为 C 并直接编译闭包。

下面是一个实现闭包的 gcc 扩展示例。

#include <stdio.h>

int(*mk_counter(int x))(void)
{
    int inside(void) {
        return ++x;
    }
    return inside;
}

int
main() {
    int (*counter)(void)=mk_counter(1);
    int x;
    x=counter();
    x=counter();
    x=counter();
    printf("%d\n", x);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)


Chr*_*ean 5

这种行为似乎是较新版本的 Clang 所特有的,并且是一种名为 "blocks"语言扩展

上C“块”维基百科文章还提供了支持该权利要求的信息:

Blocks 是Apple Inc.添加到 Clang 的 C、C++ 和 Objective-C编程语言实现的非标准扩展它使用类似于 lambda 表达式的语法在这些语言中创建闭包。为 Mac OS X 10.6+ 和 iOS 4.0+ 开发的程序支持块,尽管第三方运行时允许在 Mac OS X 10.5 和 iOS 2.2+ 以及非 Apple 系统上使用。

上面的重点是我的。在Clang 的语言扩展页面上,在“块类型”部分下,它简要概述了块类型是什么:

与函数类型一样,Block 类型是由一个结果值类型和一个非常类似于函数类型的参数类型列表组成的对。块的用途很像函数,主要区别在于除了可执行代码之外,它们还包含各种变量绑定到自动(堆栈)或托管(堆)内存。

GCC 也有一些类似于称为词法作用域嵌套函数的块。但是,维基百科关于 C 块的文章中也注意到了一些关键差异:

块表面上类似于GCC 对 C 的扩展,以支持词法作用域的嵌套函数。但是,与块不同,GCC 的嵌套函数不能在包含范围退出后调用,因为这会导致未定义的行为。

GCC 样式的嵌套函数在获取嵌套函数的地址时还需要动态创建可执行的 thunk。[...]。

上面的重点是我的。