strcmp中的奇怪返回值

fip*_*197 6 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));
}
Run Code Online (Sandbox Code Playgroud)

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

以下是我的测试环境.

  • Ubuntu 18.04 64bit
  • gcc 7.3.0
  • 铿锵6.0.0

mel*_*ene 9

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

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

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

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

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

  • 虽然有趣的是Clang和GCC可以被诱导来编译程序,使得它们各自的结果产生相同的输出或者它们没有,但是我不喜欢将其解释为优化或缺乏它是*原因*for输出不同.最好将其概括为"实施细节",因为优化只是结果可能不同的一个原因,无论是在这种特定情况下还是在一般情况下(甚至更多). (3认同)

Ben*_*rer 6

标准定义结果为strcmp负,如果在词法顺序lhs之前出现rhs,如果它们相等则为零,或者如果lhs在词汇之后出现,则为正值rhs.

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

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

背景

一个简单的实现可能只计算每个字符的差异c1 - c2,直到结果不为零或其中一个字符串结束为止.结果将是第一个字符之间的数字差异,其中两个字符串不同.

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


Som*_*ude 5

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