Тайна с выводом strcmp - Как strcmp сравнивает строки? - PullRequest
0 голосов
/ 15 февраля 2019

Я хочу знать, почему strcmp() возвращает разные значения, если они использовались более одного раза в одной и той же функции.Ниже приведена программа.В первом случае я знаю, почему он печатает -6.Но во втором случае, почему он печатает -1?

#include<stdio.h>
#include<string.h>
int main()
{
    char a[10] = "aa";
    char b[10] = "ag";
    printf("%d\n",strcmp(a, b));
    printf("%d\n",strcmp("aa","ag"));
    return 0;
}

И выходной сигнал ниже

[sxxxx@bhlingxxx test]$ gcc -Wall t51.c
[sxxxx@bhlingxxx test]$ ./a.out
    -6
    -1

Почему выходной сигнал strcmp() -1?Это компилятор, который играет здесь?Если да, то какова точная оптимизация?

Ответы [ 3 ]

0 голосов
/ 15 февраля 2019

Стандарт C говорит следующее относительно возвращаемого значения strcmp:

Раздел 7.24.4.2p3:

Функция strcmp возвращаетцелое число больше, равно или меньше нуля, соответственно, поскольку строка, на которую указывает s1, больше, равна или меньше, чем строка, на которую указывает s2

Так что до тех пор, покарезультат соответствует описанию, соответствует стандарту C.Это означает, что компилятор может выполнить оптимизацию для соответствия этому определению.

Если мы посмотрим на код сборки:

.loc 1 7 0
leaq    -32(%rbp), %rdx
leaq    -48(%rbp), %rax
movq    %rdx, %rsi
movq    %rax, %rdi
call    strcmp
movl    %eax, %esi
movl    $.LC0, %edi
movl    $0, %eax
call    printf
.loc 1 8 0
movl    $-1, %esi      # result of strcmp is precomputed!
movl    $.LC0, %edi
movl    $0, %eax
call    printf

В первом случае массивы передаются в strcmp для вызована strcmp и вызов на printf генерируется.Однако во втором случае строковые константы передаются обоим.Компилятор видит это и генерирует сам результат, оптимизируя фактический вызов strcmp, и передает жестко закодированное значение -1 в printf.

0 голосов
/ 15 февраля 2019

Единственное, что стандарт C гарантирует для strcmp, это то, что знак возвращаемого значения будет указывать направление неравенства, если оно есть, или ноль, если строки точно равны.

Хотя возвращение разницы между числовыми значениями char s на первом месте, где они отличаются, является довольно распространенной реализацией, это не требуется.Если компилятор может смотреть на строковые константы и сразу же знать, каким будет результат strcmp, он может добавить вместо него плоскость -1, 1 или 0, вместо того, чтобы прилагать усилия на самом делевызов функции.

Решение этой проблемы состоит в том, чтобы не писать код, который опирается на конкретную реализацию strcmp, независимо от того, насколько распространенной она может быть.Доверяйте только знаку возвращаемого значения.

0 голосов
/ 15 февраля 2019

из https://linux.die.net/man/3/strcmp

Функция strcmp () сравнивает две строки s1 и s2.Он возвращает целое число меньше, равно или больше нуля, если s1 найдено, соответственно, меньше, соответствует или больше s2.

Только функция strcmpобещает вернуть отрицательное значение для приведенного выше сравнения.Фактическое значение, которое будет возвращено, не указано.

Вероятно, произошло то, что для strcmp("aa","ag") компилятор знает, что результат отрицательный, и оптимизирует его до -1

...