什么,确切地说,memcmp应该返回?

时间:2017-07-07 15:55:31

标签: c language-lawyer standard-library memcmp

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

我一直在互联网上搜索,通常memcmp定义的内容如下:

  

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

从未明确说过返回的是什么,完全:它是两个字节值之间的差异,还是-1,0或1?我很困惑:

  • 在小程序中测试函数memcmp时,即使评估的两个字节之间的差异大于1或小于-1,它也会返回-1,0或1。
  • 当在Internet上查看名为memcmp的函数时,它们几乎都返回2个字节之间的差异,作为int,而不是返回-1,0或1。

由于我无法对函数memcmp进行足够精确的定义,所以我在这里提出这个问题:函数memcmp究竟应该返回什么?是否有#34;官员"源代码在哪里? (我已经看到很多memcmp的源代码,但没有人给我一个答案:我假设它们不是写在库string.h中的函数,至少在我的计算机上没有... )

4 个答案:

答案 0 :(得分:12)

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

  

比较函数返回的非零值的符号   memcmp,strcmp和strncmp由符号决定   第一对字符的值之间的差异(两者都有)   解释为unsigned char),对象不同   比较。

因此,只应将比较函数的非零返回值的符号视为有意义。这里给出的宽容度允许每个实现在其认为合适时解释这些要求。

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

答案 1 :(得分:4)

未指定确切结果的原因是

首先,确切的结果无关紧要。来电者只需知道三个结果<=>中的一个。定义的行为有效。现在规范可以说返回-1,0或1.那么为什么重要的是没有说。见第二点

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

答案 2 :(得分:2)

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

  

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

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

来源示例

我找到了一个GNU C库(glibc)的镜像,有人放在GitHub上。 source for memcmp取两个字节之间的差异(第332行),因此返回值通常不仅为-1或+1。但是,特定库可能会实现memcmp,但对目标平台最有意义。

答案 3 :(得分:2)

它没有指定返回的整数,它指定可以将结果与0进行比较。

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