【问题标题】:Why doesn't C11 support lambda functions为什么 C11 不支持 lambda 函数
【发布时间】:2013-08-11 10:39:15
【问题描述】:

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

C11 标准的开发者选择不包含这个特性有什么原因吗?

【问题讨论】:

  • 欢迎来到 SO。这个网站是针对技术问题的,所以我认为你的问题有点边界,在这里。你最好在论坛或新闻组中问这个问题。否则,您还可以轻松地在线找到 C 标准委员会会议的会议记录,并查看他们讨论的内容。我不记得最近讨论过这个。

标签: c lambda c11


【解决方案1】:

2021 年更新:基于具有极简语义的 C++ 语法的 lambdas 在今年被选入 C23。随着委员会准确确定该功能将从 C++ 和其他实现中引入的其他内容,更多细节将会浮出水面。

2016 年更新: 在 2016 年伦敦会议上,Apple 风格的 lambdas 再次提交给工作组,new proposal document 试图解决之前尝试的几个失败,整理术语和解释,并更详细地介绍如何使闭包和 lambda 成为“类 C”。

由于the reception was cautiously positive(7-0-9 是/否/弃权),看起来类似的东西很快就会进入语言。


简而言之,C 不包含 lambda 函数,因为尚未向 ISO C 工作组提出可接受的提议以包含 lambda 函数。

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

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

N1451 中的提案不能被接受有几个原因,在 N1542 中给出:

  • 最初委员会难以理解提案
  • 它使用了与现有 C 标准相矛盾的错误引用和术语
  • 它显然是模糊和不完整的
  • Apple 正在尝试为该功能申请专利(不清楚这是否是标准化的障碍,但我认为是这样)
  • 在 2010 年提出的具有全新语义的全新功能在 2011 年及时准备就绪的可能性恰好为零,并且会推迟 C11 的发布
  • 显示的块与 C++11 lambda 不兼容

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

综上所述,委员会的投票显然略微倾向于支持该功能(6-5-4 是/否/弃权),但不足以达成必要的共识以将其包括在内。

据我所知,另一个大的 C++11 lambdas 尚未被任何人提议包含在 C 中。如果你不问,你就不会得到。

任何关于 C 中 lambdas 的提议都会添加一系列关于变量生命周期和位置以及复制和分配等等的新规则。对于很多人来说,这可能开始看起来非常不像 C,与价值观在程序员背后移动或在他们的生命周期中突然发生意想不到的变化——避免这种事情是当今人们选择用 C 编写的一半原因。因此,还必须有一个真正符合 C 的“哲学”的提案才能被认真对待。我确信这是可以做到的,但是到目前为止,这两个大提案都是为具有非常不同“哲学”的语言设计的,在这种语言中,这种事情的障碍较少,并且没有必要 em> 反映了 C 目前的目的和特点。

【讨论】:

  • 我们如何向 ISO C 工作组推荐功能而不是 ISO 或 ANSI 的成员?我想建议 C2x 支持 UTF-8 类型。
  • 没有任何可用的形式。
【解决方案2】:

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

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

添加这些高级快捷方式中的任何一个都可能使编程更加舒适,但这是以使语言更加复杂为代价的,这一点不容小觑。这是一个滑坡,直接导致了C++变成的烂摊子。

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

【讨论】:

  • 不同意最后一段。这不是“没有必要”。与 lambdas stackoverflow.com/questions/13722426/… 相比,函数指针不太可能被内联,这会导致指针重复函数调用对于 qsort 等操作变慢
  • 最后一点是不正确的——静态函数/结构既不是可重入的,也不是线程安全的,而 lambda 是。
【解决方案3】:

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

一方面,Lisp 从 1958 年诞生就一直支持 lambda 表达式。C 编程语言诞生于 1972 年。所以 lambda 表达式其实比 C 有更长的历史。所以如果你问为什么 C11 不支持'不支持lambda表达式,同样的问题可以问C89。

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

最后,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
*/

【讨论】:

    猜你喜欢
    • 2012-01-27
    • 1970-01-01
    • 1970-01-01
    • 2011-04-21
    • 2022-08-18
    • 2012-11-11
    • 2014-03-13
    • 2011-11-22
    相关资源
    最近更新 更多