Ahm*_*zan 32 c c++ linux strcmp
strcmp当我注意到这一点时,我正在玩,这里是代码:
#include <string.h>
#include <stdio.h>
int main(){
//passing strings directly
printf("%d\n", strcmp("ahmad", "fatema"));
//passing strings as pointers
char *a= "ahmad";
char *b= "fatema";
printf("%d\n",strcmp(a,b));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出是:
-1
-5
Run Code Online (Sandbox Code Playgroud)
不应该strcmp一样吗?为什么,我给我传递一个字符串作为不同的值"ahmad"或作为char* a = "ahmad".将值传递给函数时,它们是否在其堆栈中分配?
Sha*_*our 46
您很可能会看到编译器优化的结果.如果我们在godbolt上使用gcc测试代码,使用-O0优化级别,我们可以看到它没有调用的第一种情况strcmp:
movl $-1, %esi #,
movl $.LC0, %edi #,
movl $0, %eax #,
call printf #
Run Code Online (Sandbox Code Playgroud)
由于你使用常量作为strcmp的参数,编译器能够执行常量折叠并在编译时调用编译器内在函数并生成-1then,而不必strcmp在运行时调用,这在标准库中实现并且将具有不同的实现然后可能更简单的编译时间strcmp.
在第二种情况下,它确实生成一个调用strcmp:
call strcmp #
movl %eax, %esi # D.2047,
movl $.LC0, %edi #,
movl $0, %eax #,
call printf #
Run Code Online (Sandbox Code Playgroud)
这是与事实相符的gcc有STRCMP一个内置的,这是什么gcc在常量折叠期间使用的内容.
如果我们使用-O1优化级别或更高级别 进一步测试gcc能够折叠两种情况,结果将-1适用于两种情况:
movl $-1, %esi #,
movl $.LC0, %edi #,
xorl %eax, %eax #
call printf #
movl $-1, %esi #,
movl $.LC0, %edi #,
xorl %eax, %eax #
call printf #
Run Code Online (Sandbox Code Playgroud)
启用了更多优化选项后,优化器能够确定a并b指向编译时已知的常量,并且还可以在编译期间计算strcmp此情况的结果.
我们可以gcc通过使用-fno-builtin标志构建并观察调用来确认是使用内置函数strcmp将为所有情况生成.
clang略有不同之处在于它根本不会折叠-O0但会折叠-O1两者之间.
注意,任何负面结果都是完全一致的,我们可以通过参考草案C99标准部分看到7.21.4.2strcmp函数说明(强调我的):
Run Code Online (Sandbox Code Playgroud)int strcmp(const char *s1, const char *s2);strcmp函数返回一个大于,等于或小于零的整数,因为s1指向的字符串大于,等于或小于 s2指向的字符串.
technosurus指出,strcmp指定将字符串视为由无符号字符组成,这在C99中有所7.21.1说明:
对于本子条款中的所有函数,每个字符都应解释为它具有unsigned char类型(因此每个可能的对象表示都是有效的并且具有不同的值).
dav*_*mac 13
我想你相信回归的价值 strcmp应该以某种方式依赖于以函数规范未定义的方式传递给它的输入字符串.这是不正确的.例如,参见POSIX定义:
http://pubs.opengroup.org/onlinepubs/009695399/functions/strcmp.html
完成后,如果s1指向的字符串分别大于,等于或小于s2指向的字符串,strcmp()将返回大于,等于或小于0的整数.
这正是你所看到的.实现不需要对确切的返回值做出任何保证- 只有在适当的时候小于零,等于零或大于零.
| 归档时间: |
|
| 查看次数: |
1852 次 |
| 最近记录: |