2

我想知道函数memcmp必须返回什么。

我一直在互联网上搜索,通常,memcmp定义如下所示:

memcmp() 函数返回一个大于、等于或小于零的整数,相应地,因为 s1 指向的对象大于、等于或小于 s2 指向的对象。

从来没有明确说明返回的是什么:是两个字节值之间的差异,还是 -1、0 或 1?我很困惑:

  • 在一个小程序中测试该函数memcmp时,它返回 -1、0 或 1,即使评估的两个字节之间的差值高于 1 或低于 -1。
  • 在查看memcmpInternet 上命名的函数时,它们几乎都以 int 形式返回 2 个字节之间的差异,而不是返回 -1、0 或 1。

由于我无法对函数进行足够精确的定义,所以memcmp我在这里问这个问题:函数memcmp应该返回什么?某处是否有“官方”源代码?(我看过很多源代码,memcmp但没有一个给我答案:然后我假设它们不是库 string.h 中编写的函数,至少不是在我的计算机上......)

4

4 回答 4

12

memcmp()标准未指定返回的特定值。C11 标准草案确实在§7.24.4 1中说:

比较函数 memcmp、strcmp 和 strncmp 返回的非零值的符号由被比较对象中不同的第一对字符(均解释为无符号字符)的值之间的差异符号确定。

因此,只有来自比较函数的非零返回值的符号才应该被认为是有意义的。这里给出的范围允许每个实现在它认为合适的时候解释这些要求。

另外,请注意没有“官方源代码”;标准是 C 实现必须遵守的文档。即使阅读您正在使用的实现的源代码来查找用于生成memcmp()返回值的底层方法,在代码中使用这些值充其量也是不可移植的,并且容易受到该实现的未来更改的影响。

于 2017-07-07T16:02:25.653 回答
5

未指定确切结果的原因是

首先,确切的结果并不重要。调用者只需要知道三个结果之一<=>。定义的行为有效。现在规范可以说返回 -1、0 或 1。那么为什么不说这很重要。见第二点

第二。通过不指定确切的结果,实现者可以编写非常有效的代码。memcmp 可以通过计数位或做一些聪明的和来实现。或者。xor 等不会自然产生 1 或 -1。因此规范对确切的返回值保持沉默。

于 2017-07-07T16:14:36.533 回答
2

正如@EugeneSh 所说,它没有定义。除了您引用的部分之外,POSIX规范还说:

非零返回值的符号应由在被比较的对象中不同的第一对字节(均解释为类型无符号字符)的值之间的差异符号确定。

因此,只有零/非零和正/负是有意义的测试,适用于 的返回值memcmp。不要依赖实际值,因为它们可能在不同的 C 库(甚至可能是处理器架构)之间有所不同。

源示例

我在 GitHub 上找到了 GNU C 库 (glibc) 的镜像。for的memcmp取两个字节之间的差值(第 332 行),因此返回值一般不会只有 -1 或 +1。然而,一个特定的库可以实现,memcmp但对目标平台最有意义。

于 2017-07-07T15:59:59.490 回答
2

它没有指定将返回什么整数,它指定结果可以与0.

如果实现完成此测试,则实现返回的任何值都是正确的。

于 2017-07-07T16:13:26.487 回答