为什么C11不支持lambda函数

Mik*_*her 7 c lambda c11

新的C++ 11标准支持lambda函数,我认为这是一个有用的功能.我知道C和C++标准彼此不同但我不明白为什么C11不支持lambda函数.我认为它可能有很多用途.

有没有理由为什么C11标准的开发人员选择不包含此功能?

dpi*_*dpi 9

C旨在成为一种小而简单的语言.当通过更简单的方法完成相同的事情时,它故意省略高级功能.它旨在仅提供便携式编程绝对必要的基本功能.

C没有引用,因为它们只是指针.C没有类,继承和虚函数,因为你可以只使用结构,使自己使用函数指针的虚函数表.它没有垃圾收集器,因为程序员可以自己跟踪内存分配,它没有模板,因为它们实际上只是宏.如果需要例外,可以使用longjmp,而不是命名空间,只需在名称中添加前缀即可.

添加任何这些高级快捷方式可能会使编程更加舒适,但这是以使语言更复杂为代价的,这一点不容小觑.这是一个滑坡,直接导致C++变得混乱.

C没有lambda函数,因为它们不是必需的.相反,您可以使用静态函数并将上下文放在结构中.


Leu*_*nko 7

2016年更新:在2016年伦敦会议上,工作组再次向工作组提交了带有封闭装置的苹果风格的lambdas,这是一份新的提案文件,试图解决上一次尝试的几个失误,整理术语和解释,然后进入关于如何将闭合和lambdas制成"C-like"的更多细节.

由于接待是谨慎积极的(7-0-9是/否/弃权),看起来很可能类似于此的东西将很快成为语言.


简短的回答就是C不包含lambda函数,因为还没有人向ISO C工作组提出可接受的建议来包含lambda函数.

您可以在此处查看工作组讨论的一些提案列表:http://www.open-std.org/jtc1/sc22/wg14/www/documents

我在该列表中找到的任何类型的lambdas的唯一提议是Apple的块(如Yu Hao的回答所示),在N1451号文件中.该提议将在N1483中进一步讨论,将其与C++ lambdas进行比较,并将N1493N1542与提交这些文档的会议记录进行比较.

在N1542中,有几个原因导致N1451中的提案无法被接受:

  • 最初,委员会很难理解该提案
  • 它使用与现有C标准相矛盾的错误引用和术语
  • 它显然含糊不清
  • Apple正在尝试为该功能申请专利(不清楚这是否是标准化的障碍,但我会这么认为)
  • 2010年提出的全新语义的全新特征在2011年准备就绪的可能性非常小,并且会阻碍C11的发布
  • 所呈现的块与C++ 11 lambdas不兼容

看起来他们还不相信它目前正在展示足够的实用性.C标准化显然试图非常保守,只有一个主要的编译器实现该功能,他们可能想等待,看看它如何与C++ lambdas竞争,以及是否有其他人选择它.在多个编译器提供它之前,它不是真正的"C"功能而不是"Clang"功能.

所有这一切,委员会的投票显然略微倾向于支持该功能(6-5-4是/否/弃权),但还不足以达成必要的共识以包含它.

据我所知,另一个大的,C++ 11 lambdas,没有被提议任何人包含在C中; 如果你不问你没有得到.

任何关于C语言中的lambdas的提议都会增加一系列关于变量生命周期和位置以及复制和分配的新规则......等等.对于很多人来说,这可能会开始看起来非常类似于C,值会被移动在程序员的背后或者他们的生命周期突然出现意外变化 - 避免这种情况是人们现在选择用C语言写作的一半原因.因此,在认真对待之前,还必须有一个实际上符合C的"哲学"的提案.我确信这可以做到,但到目前为止,两个大的提议都是针对具有非常不同的"哲学"的语言设计的,这种事情不是一个障碍,并不一定反映C的目的和性质他们目前的立场.


Yu *_*Hao 4

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

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

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

最后,C 和 C++ 总是互相学习,所以也许下一个 C 标准也会如此。现在,您可以看一下Blocks,这是 Apple 添加的非标准扩展。这是来自维基百科的示例代码:

#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
*/
Run Code Online (Sandbox Code Playgroud)