strcmp() возвращает разные значения для одних и тех же сравнений строк [дубликаты]

char s1[] = "0";
char s2[] = "9";
printf("%d\n", strcmp(s1, s2));   // Prints -9
printf("%d\n", strcmp("0", "9")); // Prints -1

Почему strcmp возвращает разные значения, когда получает одни и те же параметры?

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


person Bilow    schedule 12.10.2015    source источник
comment
ideone.com/S3dYMQ, если кто-то хочет поиграть...   -  person Fantastic Mr Fox    schedule 13.10.2015


Ответы (2)


Я предполагаю, что вы используете GCC при компиляции, я пробовал на 4.8.4. Хитрость здесь в том, что GCC понимает семантику некоторых стандартных библиотечных функций (одной из них является strcmp). В вашем случае компилятор полностью исключит второй вызов strcmp, потому что он знает, что результат strcmpданных строковых констант "0" и "9" будет отрицательным, а вместо выполнения вызова будет использоваться стандартное совместимое значение (-1). Он не может сделать то же самое с первым вызовом, потому что s1 и s2 могли быть изменены в памяти (представьте себе прерывание или несколько потоков и т. д.).

Вы можете провести эксперимент, чтобы убедиться в этом. Добавьте к массивам квалификатор const, чтобы GCC знал, что их нельзя изменить:

const char s1[] = "0";
const char s2[] = "9";
printf("%d\n", strcmp(s1, s2));   // Now this will print -1 as well
printf("%d\n", strcmp("0", "9")); // Prints -1

Вы также можете просмотреть вывод ассемблера из компилятора (используйте флаг -S).

Однако лучший способ проверить это использовать -fno-builtin, который отключает эту оптимизацию. С этой опцией ваш исходный код будет печатать -9 в обоих случаях.

person Geza Lore    schedule 12.10.2015
comment
Я думаю, что часть не может быть неправильной, и это действительно произошло не с заданными настройками оптимизации. - person Carsten S; 23.10.2020

Разница связана с реализацией strcmp. Пока он соответствует (‹0, 0, >0), это не должно иметь значения для разработчика. Вы не можете полагаться ни на что другое. Насколько вам известно, исходный код может определять, что он должен быть отрицательным, и случайным образом генерировать отрицательное число, чтобы сбить вас с толку.

person ergonaut    schedule 12.10.2015