strcmp中的奇怪返回值[重复]

问题描述 投票:6回答:4

在检查strcmp函数的返回值时,我在gcc中发现了一些奇怪的行为。这是我的代码:

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

char str0[] = "hello world!";
char str1[] = "Hello world!";

int main() {
    printf("%d\n", strcmp("hello world!", "Hello world!"));
    printf("%d\n", strcmp(str0, str1));
}

当我用clang编译它时,对strcmp的两次调用都返回32.但是,当用gcc编译时,第一个调用返回1,第二个调用返回32.我不明白为什么第一次和第二次调用strcmp返回不同的值使用gcc编译时。

以下是我的测试环境。

  • Ubuntu 18.04 64bit
  • gcc 7.3.0
  • 铿锵6.0.0
c gcc clang
4个回答
9
投票

看起来你没有启用优化(例如-O2)。

从我的测试看起来gcc总是用常量参数识别strcmp并优化它,即使使用-O0(没有优化)。 Clang至少需要-O1才能这样做。

差异来自于:clang生成的代码两次调用strcmp,但gcc生成的代码在第一种情况下只执行printf("%d\n", 1),因为它知道'h' > 'H'(ASCIIbetically,即)。它只是不断折叠,真的。

实例:https://godbolt.org/z/8Hg-gI

正如其他答案所解释的那样,任何正值都将表明第一个字符串大于第二个字符串,因此编译器优化器只选择1strcmp库函数显然使用不同的值。


6
投票

如果strcmp在词汇顺序中出现在lhs之前,则标准将rhs的结果定义为负,如果它们相等则为零,如果lhsrhs之后出现https://en.cppreference.com/w/c/string/byte/strcmp则为正值。

这取决于实现如何实现它以及返回什么。您不能依赖程序中的特定值,否则它们将无法移植。只需检查比较(<,>,==)。

c1 - c2

背景

一个简单的实现可能只计算每个字符https://sourceware.org/git/?p=glibc.git;a=blob_plain;f=string/strcmp.c;hb=HEAD的差异,直到结果不为零或其中一个字符串结束。结果将是第一个字符之间的数字差异,其中两个字符串不同。

例如,这个GLibC实现:strcmp


5
投票

strcmp函数仅指定为返回大于零,零或小于零的值。没有具体说明这些正面和负面价值必须是什么。


3
投票

没有指定man page在字符串不相等的情况下返回的确切值。来自#include <string.h> int strcmp(const char *s1, const char *s2); int strncmp(const char *s1, const char *s2, size_t n);

str1

如果找到s1(或其前n个字节),则strcmp()和strncmp()函数返回小于,等于或大于零的整数,小于,匹配或大于s2 。

由于str2比qazxswpoi更大,因此值必须为正,这两种情况都是如此。

至于两个编译器之间的区别,似乎clang返回不匹配的相应字符的ASCII值之间的差异,而gcc选择简单的-1,0或1.两者都是有效的,所以你的代码应该只需要检查值是0,大于0还是小于0。

© www.soinside.com 2019 - 2024. All rights reserved.