strcmp中的奇怪返回值

时间:2018-09-14 14:30:34

标签: c gcc clang

在检查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。使用gcc编译时,对strcmp的第二次调用返回不同的值。

下面是我的测试环境。

  • Ubuntu 18.04 64位
  • gcc 7.3.0
  • c 6.0.0

3 个答案:

答案 0 :(得分:9)

您似乎没有启用优化功能(例如-O2)。

从我的测试看来,gcc始终会识别具有恒定参数的strcmp并对其进行优化,即使使用-O0也是如此(无优化)。 Clang至少需要-O1才能这样做。

这就是区别的出处:clang产生的代码两次调用strcmp,但是gcc产生的代码在第一种情况下只执行printf("%d\n", 1),因为它知道'h' > 'H'(从ASCII(按字母顺序表示)。真的,它只是不断折叠。

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

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

答案 1 :(得分:6)

如果strcmp以词法顺序出现在lhs之前,则标准将rhs的结果定义为负数;如果相等,则为零;如果{{1} }出现在lhs之后。

具体取决于实现方式,实现方式以及返回的内容。您不得依赖程序中的特定值,否则它们将不可移植。只需检查比较(<,>,==)即可。

请参见https://en.cppreference.com/w/c/string/byte/strcmp

背景

一个简单的实现可能只是计算每个字符rhs的差,然后这样做直到结果不为零或字符串之一结束。结果将是第一个字符之间的数字差异,其中两个字符串不同。

例如,此GLibC实现:https://sourceware.org/git/?p=glibc.git;a=blob_plain;f=string/strcmp.c;hb=HEAD

答案 2 :(得分:5)

仅指定strcmp函数以返回大于零,零或小于零的值。没有规定那些正负值是什么。