当将STRCMP不会返回-1,0或1?(When will strcmp not return -1

2019-07-04 04:02发布

从手册页:

所述的strcmp()和STRNCMP()函数返回小于整数,等于或大于零,如果S1(或其前n个字节)被发现,分别为小于,以匹配或大于s2 。

在℃实施例的代码(打印-15我的机器上,交换TEST1和TEST2反转值):

#include <stdio.h>
#include <string.h>

int main() {
    char* test1 = "hello";
    char* test2 = "world";
    printf("%d\n", strcmp(test1, test2));
}

我发现这个代码 (取自这个问题 ,依靠的不是-1,0和1(它使用的返回值在其他的strcmp作为东西值) qsort )。 对我来说,这是很可怕的风格和依赖于未记录的功能。

我想我有两个相关的问题:

  • 有什么东西在C标准,它定义了返回值是除了小于,大于或等于零? 如果没有,是什么标准的实现呢?
  • 是返回值跨越Linux,Windows和BSD系统是否一致?

编辑:

离开我的电脑5分钟后,我意识到,其实也有与有问题的代码没有错误。 我打了,我读的意见/应答前想通了部分,但我离开了他们那里,以保持评论相关。 我认为这仍然是一个有趣的问题,并可能会导致对使用其他语言总是返回-1,0或1程序员打嗝(如Python的似乎要做到这一点,但它不记录这样)。

FWIW,我认为,依靠比记录的行为以外的东西是不好的风格。

Answer 1:

在C99标准

7.21.4.2 The strcmp function

“的strcmp函数返回一个整数greater than, equal to, or less than zero ,相应地作为指向的字符串S1大于,等于,或小于字符串s2指向于”。

这意味着标准并不保证有关-101它可以根据操作系统而变化。

你所得到的值之差wh15

在你的情况helloworld如此'h'-'w' = -15 < 0that's why strcmp retuns -15



Answer 2:

有什么东西在C标准,它定义了返回值是除了小于,大于或等于零?

号最紧密限制是它应当是零,小于零或大于零,如中指定该特定功能的文档 。

如果没有,是什么标准的实现呢?

有作为“的标准实现”没有这样的事。 即使有,它很可能只是

return zero, less than zero or more than zero;

:-)

是返回值跨越Linux,Windows和BSD系统是否一致?

我可以证实,它跨Linux和OS X的一致为10.7.4(具体地讲,它是-1,0或+1)。 我不知道的Windows的想法,但我敢打赌,微软人使用-2和+3只是为了打破代码:P

此外,还让我指出,你已经完全误解了代码的作用。

我发现,靠的不是-1,0和1(它使用的返回值的qsort)其他STRCMP是东西值这个代码(由这个问题采取了)。 对我来说,这是很可怕的风格和依赖于未记录的功能。

不,它实际上没有。 C标准库的设计与一致性和易用性考虑使用。 也就是说,什么样qsort()需要的是,它的比较函数返回一个负或正数或零-正是strcmp()是保证做到。 因此,这不是“可怕的风格”,这是完全符合标准的代码不依赖于未记录的功能。



Answer 3:

•Is there something in the C standard that defines what the return values are besides less than, greater than, or equal to zero? If not, what does the standard implementation do?

不,你提到自己的男人说less than, equal to, or greater than zero ,这就是标准的为好。

•Is the return value consistent across the Linux, Windows and the BSDs?

没有。

在Linux(openSUSE的12.1,内核3.1)用gcc我得到-15 / 15取决于如果test1test2是第一。
在Windows 7(VS 2010)我得到-1 / 1

基于所述松散认定中strcmp()均为优良。


...that relies on the values of strcmp being something other than -1, 0 and 1 (it uses the return value in qsort).

一个有趣的不是你......如果你看一看的人进行qsort()的例子有几乎一样的,你贴使用铃代码strcmp()原因是该compairator函数qsort()要求实际上是从返回一个非常适合strcmp()

如果第一个参数被认为是比上述第二分别小于,等于或大于比较函数必须返回一个整数比小于零,等于,或更大 。



Answer 4:

在现实中,返回值strcmp可能是在那个不同,仅仅是因为返回此不同的是很多比做一个附加条件分支将其转换为-1或更有效的第一位置字节的值之间的差异1.不幸的是, 一些破碎的软件已经知道,假设结果符合8位,从而导致严重的安全漏洞 。 总之,你不应该使用什么,但结果的符号。

有关问题的详细信息,请阅读我上面链接的文章:

https://communities.coverity.com/blogs/security/2012/07/19/more-defects-like-the-mysql-memcmp-vulnerability



Answer 5:

在此页:

所述的strcmp()函数比较字符串指向S1到串s2指向到。 一个非零的返回值的符号由第一字节对(均为解释为类型无符号字符),在不同的字符串被比较的值之间的差的符号来确定。

这里是FreeBSD的strcmp的实现。

#include <string.h>

/*
 * Compare strings.
 */
int
strcmp(s1, s2)
    register const char *s1, *s2;
{
    while (*s1 == *s2++)
        if (*s1++ == 0)
            return (0);
    return (*(const unsigned char *)s1 - *(const unsigned char *)(s2 - 1));
}


Answer 6:

从手册页:

返回值的strcmp()和STRNCMP()函数返回小于整数,等于或大于零,如果S1(或其前n个字节)被发现,分别为小于,以匹配或更大比s2。

它仅规定它是大于或小于0,不说有关特定值什么,这些都是指定我想。

遵循于SVR4,4.3BSD,C89,C99。 这是说在标准它是包括在内。 该功能必须存在并按规定的行为,但规格并没有说明实际返回的值什么,所以你不能依靠他们。



Answer 7:

还有在谈到返回的值C标准没有strcmp() (即,除了该值的符号 ):

7.21.4.2该功能的strcmp

概要

 #include <string.h> int strcmp(const char *s1, const char *s2); 

描述

所述的strcmp函数比较字符串指向S1到串s2指向到。

返回

所述的strcmp函数返回一个整数大于,等于,或小于零,相应地作为指向的字符串S1大于,等于,或小于字符串s2指向到。

因此,它是很清楚,使用比返回值的符号以外的任何是一个贫穷的做法。



文章来源: When will strcmp not return -1, 0 or 1?
标签: c strcmp