为什么C11不支持Lambda函数

10
新的C++11标准支持lambda函数,我认为这是一个非常有用的特性。我知道C和C++标准之间存在差异,但我不明白为什么C11不支持lambda函数。我认为它可能有很多用途。
开发C11标准的人员选择不包括这个特性,是否有原因呢?

欢迎来到SO。这个网站是用于技术问题的,所以我认为你的问题有些界限性。你最好在论坛或新闻组中提问。否则,你也可以轻松地在网上找到C标准委员会会议记录,并查看他们讨论的内容。我不记得最近有讨论过这个问题。 - Jens Gustedt
3个回答

11

2021更新:基于C++语法的具有极简语义的lambda表达式已于今年被投票纳入C23。随着委员会确定该功能将从C++和其他实现中带来什么,更多细节将浮出水面。

2016更新:在伦敦2016年的会议上,苹果风格的带闭包的lambda表达式再次提交给工作组,提出了一份新提案文档,试图解决之前尝试中的一些缺陷,整理术语和解释,并详细说明如何使闭包和lambda表达式“类似于C”。由于反应谨慎积极(7-0-9赞成/反对/弃权),很可能很快就会有类似的东西进入语言中。


简而言之,C语言没有包含lambda函数是因为尚未有人向ISO C工作组提出可接受的lambda函数提案。
您可以在此处查看工作组讨论的一些提案列表:http://www.open-std.org/jtc1/sc22/wg14/www/documents
我能找到的有关lambda的唯一提案是苹果公司的blocks(正如余浩的回答中所示),在文档N1451中。该提案在N1483中有进一步讨论,将其与C ++ lambda进行比较,并且N1493N1542是演示这些文档的会议记录。
在N1542中给出了几个原因,说明为什么无法接受N1451中的提案。
  • 最初,委员会很难理解这个提案
  • 它使用了不正确的引用和术语,与现有的C标准相矛盾
  • 它显然含糊不清且不完整
  • 苹果公司正在试图申请该功能的专利(不清楚这是否是标准化的障碍,但我认为是)
  • 一个完全新的功能,具有完全新的语义,在2010年提出,几乎没有机会在2011年之前准备好,并且会拖延C11的发布
  • 所呈现的块与C++11的lambda表达式不兼容

此外,他们似乎并不认为它目前展示了足够的实用性。 C标准化显然试图非常保守,只有一个主要的编译器实现该功能,他们很可能希望等待并观察它如何与C++ lambda竞争,以及是否有其他人选择使用它。除非多个编译器都提供它,否则它不是一个“C”特性,而是一个“Clang”特性。

尽管如此,委员会的投票结果似乎略微倾向于该功能(6-5-4赞成/反对/弃权),但不足以达成必要的共识来包含它。

据我所知,另一个大的特性C++11 lambda表达式还没有被任何人提议纳入C语言;如果你不提出来就得不到。
在C语言中,任何lambda表达式的提议都会增加一系列新规则,包括变量生命周期、位置、复制和分配等等。对于很多人来说,这可能看起来非常不像C语言,值在程序员背后被移动或者生命周期突然意外改变 - 避免这种情况是人们现在选择使用C语言的原因之一。因此,在被认真考虑之前,还必须有一个符合C语言“哲学”的提案。我相信这是可以做到的,但目前为止,两个大的提案都是为具有非常不同“哲学”的语言设计的,在这种语言中,这种情况不是障碍,而且不一定反映C语言当前的目的和特点。

我们如何向ISO C工作组建议功能,而不是ISO或ANSI的成员?我想向C2x建议支持UTF-8类型。 - MarcusJ
不以任何可用形式返回。 - MarcusJ

10

C语言旨在成为一种小型且简单的语言。当可以通过更简单的方法完成相同的事情时,它故意省略了高级特性。它旨在仅提供绝对必要的基本功能,以用于可移植编程。

C语言没有引用,因为它们只是指针。C语言没有类、继承和虚函数,因为你可以使用结构体并使用函数指针自己制作虚表。它没有垃圾回收器,因为程序员可以自己跟踪内存分配,它没有模板,因为它们实际上只是宏。如果需要异常处理,可以使用longjmp,而不是命名空间,只需向名称添加前缀即可。

添加任何这些高级快捷方式可能会使编程变得更加舒适,但代价是使语言变得更加复杂,这不能低估。这是一个非常棘手的问题,直接导致了C++所变成的混乱状态。

C语言没有lambda函数,因为它们并不是真正必要的。相反,您可以使用静态函数并将上下文放入结构中。


不同意最后一段。它并非“不是真正必要的”。函数指针比Lambda更不可能被内联,这会导致像qsort这样的操作通过指针进行重复函数调用,从而降低速度。参考链接:https://dev59.com/q2Yr5IYBdhLWcg3wYZOD - SwiftMango
最后那点是错误的 - 静态函数/结构既不可重入也不线程安全,而 Lambda 表达式是线程安全的。 - Lelanthran

4

这只是我的个人意见,因为我不知道委员会的想法。

一方面,自1958年以来,Lisp一直支持lambda表达式。而C编程语言诞生于1972年。因此,lambda表达式实际上比C更具历史悠久性。因此,如果你问为什么C11不支持lambda表达式,同样的问题也可以问及C89。

另一方面, lambda表达式始终是函数式编程的一种东西,并逐渐被吸收到命令式编程语言中。一些“高级”语言(例如Java,在计划的Java 8之前)尚未支持它。

最后,C和C ++始终互相学习,因此也许会出现在下一个C标准中。目前,您可以查看苹果添加的非标准扩展。以下是维基百科上的示例代码:

#include <stdio.h>
#include <Block.h>
typedef int (^IntBlock)();

IntBlock MakeCounter(int start, int increment) {
        __block int i = start;

        return Block_copy( ^ {
                int ret = i;
                i += increment;
                return ret;
        });

}

int main(void) {
        IntBlock mycounter = MakeCounter(5, 2);
        printf("First call: %d\n", mycounter());
        printf("Second call: %d\n", mycounter());
        printf("Third call: %d\n", mycounter());

        /* because it was copied, it must also be released */
        Block_release(mycounter);

        return 0;
}
/* Output:
        First call: 5
        Second call: 7
        Third call: 9
*/

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接