在检查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编译时。
以下是我的测试环境。
看起来你没有启用优化(例如-O2
)。
从我的测试看起来gcc总是用常量参数识别strcmp
并优化它,即使使用-O0
(没有优化)。 Clang至少需要-O1
才能这样做。
差异来自于:clang生成的代码两次调用strcmp
,但gcc生成的代码在第一种情况下只执行printf("%d\n", 1)
,因为它知道'h' > 'H'
(ASCIIbetically,即)。它只是不断折叠,真的。
实例:https://godbolt.org/z/8Hg-gI
正如其他答案所解释的那样,任何正值都将表明第一个字符串大于第二个字符串,因此编译器优化器只选择1
。 strcmp
库函数显然使用不同的值。
如果strcmp
在词汇顺序中出现在lhs
之前,则标准将rhs
的结果定义为负,如果它们相等则为零,如果lhs
在rhs
之后出现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
strcmp
函数仅指定为返回大于零,零或小于零的值。没有具体说明这些正面和负面价值必须是什么。
没有指定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。