memmem成为GNU扩展的原因是什么?

12

C语言中,memmem函数用于在内存区域中定位特定字节序列。它可以被看作是专门用于以空字符结尾的字符串的strstr函数。

为什么这个函数作为GNU扩展而不是直接包含在标准库中?手册中指出:

这个函数在Linux库中一直存在问题,直到libc 5.0.9版本(包括该版本),其中needle和haystack参数被交换,并返回指向第一个出现的needle末尾的指针。

新旧的libc都有一个错误,即如果needle为空,则返回haystack-1(而不是haystack)。而glibc 2.0则更糟糕,返回指向haystack最后一个字节的指针。这在glibc 2.1中得到了修复。

我看到它经历了几个修复,但我想知道为什么它没有像某些发行版上的strstr函数那样被直接提供(如果不是更多)。它仍然会带来实现问题吗?

编辑(动机):如果标准是反过来决定的:包括memmem但不包括strstr,那么我就不会提出这个问题。实际上,strstr可以是以下内容:

memmem(str, strlen(str), "search", 6);

有点棘手,但仍然是一个相当“逻辑”的一行代码,考虑到在C函数中通常需要同时要求数据块和其长度。

编辑(2):来自评论和答案的另一个动机。引用Theolodis的话:

并非每个函数都对每个C开发人员都必要,或者至少大多数开发人员都必要,因此标准库实际上会使得库变得不必要巨大。

好吧,我完全同意,当涉及到使库更轻、更快时,我总是参与其中。但是...为什么既有strncpy又有memcpy(来自keltar的评论)...?我差点可以问:为什么可怜的memmem被“黑羊化”了呢?


3
我倾向于这样说:“因为它没有被添加到标准中。” - Theolodis
1
我已经阅读了足够多关于UNIX和Linux的书籍和参考资料,以知道事情不会无缘无故地被遗忘。毕竟,这个函数已经被记录为有缺陷,并得到了关注。我很好奇它为什么不是一个通常的函数。毕竟,鉴于针/堆栈长度,NULL终止变得毫无意义,但strstr是标准的。 - John WH Smith
标准中缺少许多东西,它无法包含所有内容。即使是相当庞大且远远超出纯C标准的glibc也缺少一些非常方便的BSD函数,例如strlcpy,只能使用笨重的strncpy。 - keltar
我已经阅读了足够多关于UNIX和Linux的书籍和参考资料,以知道事情不会无缘无故地被遗忘。-- 当然会。 - Keith Thompson
请注意,手册中提到的“libc 5.0.9”显然是一个旧的Linux特定的C库;该版本于1995年发布。它已被GNU libc实现的glibc所取代。 - Keith Thompson
显示剩余2条评论
1个回答

4

历史上,在标准的第一次修订之前,C语言是由编译器作者开发的。

对于strstr函数来说,情况略有不同,因为它是由C委员会引入的。C89理由文件告诉我们:

"strstr函数是委员会的发明。它被包括作为高效算法的钩子,或者用于内建的子字符串指令。"

C委员会没有解释为什么没有制作一个更通用、不限于字符串的函数,因此任何推理都只能是猜测。我唯一的猜测是该用例被认为不重要到足以有一个通用的memmem而不是strstr。请记住,在C的目标中有这个要求(在C99的理由中)"保持语言简单"。即使是POSIX也没有考虑将其纳入其中。

无论如何,据我所知,没有人提出任何缺陷报告或建议,要求包含memmem


1
只是为了确保:在C99 Rationale中的这个引用中,您是否将“简单”理解为“对于核心/语言开发人员简单”还是“对于用户,即C应用程序开发人员简单”?我会觉得memmemstrstr稍微容易编程一些(虽然这可能只是我的感觉),因此后者确实有意义(strstr更常见和直观)。 - John WH Smith

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