这个C代码怎么能有lambda

时间:2017-01-17 15:16:46

标签: c lambda

此代码:

#include <stdio.h>

int main()
{
    void (^a)(void) = ^ void () { printf("test"); } ;
    a();
}

使用clang -Weverything -pedantic -std = c89(版本clang-800.0.42.1)编译而不发出警告并打印test

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

2 个答案:

答案 0 :(得分:2)

这种行为似乎对较新版本的Clang来说是特定的,并且是language extension called "blocks"

Wikipedia article on C "blocks"还提供支持此声明的信息:

  

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

上面的重点是我的。在Clang's language extension page, under the "Block type" section上,它简要概述了Block类型:

  

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

GCC也有类似于名为词法范围的嵌套函数的块。但是,在维基百科关于C块的文章中也有一些关键的差异:

  

块与 GCC扩展C表面具有表面上的相似性,以支持词法范围的嵌套函数。但是,GCC的嵌套函数与块不同,不得在之后调用包含范围已退出,因为这会导致未定义的行为。

     

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

上面的重点是我的。

答案 1 :(得分:2)

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

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

以下是实现闭包的gcc扩展示例。

android { 
    aaptOptions.cruncherEnabled = false
    aaptOptions.useNewCruncher = false
}