Как эта функция C int работает без оператора return?

У меня есть код C, который я был уверен, что это не сработает, но это так.

#include 

int* find (int* a, int val) {
    if (*a == val)
        return a;
    else
        find(a+1, val);
}

int main() {
    int a[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    int *b;

    b = find(a, 7);

    printf("%d\n", *b);

    return 0;
}

Конечно, я получаю предупреждение от gcc, так как в нем отсутствует оператор return внутри ветви else функции find . Однако он работает отлично.

Почему это происходит? Как известно, чтобы вернуть int через рекурсивную функцию? Конечно, последние вызовы возвращают int, но я вызываю его в пустотном контексте.

0
nl ja de
Что такое trova ?
добавлено автор asm, источник
Ops. Я забыл перевести его, trova является итальянским для `find '. Сожалею.
добавлено автор Zagorax, источник
Теперь это исправлено. Извините за эту немую ошибку.
добавлено автор Zagorax, источник
Если вы откажетесь сообщить нам, что делает trova , как вы ожидаете значимого ответа? Для всех, кого мы знаем, он немедленно вызывает exit (0); .
добавлено автор Kerrek SB, источник
Он не компилируется, в вашей программе нет определения функции trova . Вставьте скомпилированный тестовый код.
добавлено автор ouah, источник
что делает trova ?
добавлено автор ogzd, источник

4 ответы

Этот код не является допустимым кодом C, а поведение такого кода не определено.

Одна из причин, почему это работает, может заключаться в том, что после последнего вызова find нет операции после того, как может получить возвращаемое значение рекурсивного вызова, остающегося в регистре возврата (возможно, EAX).

But again - the behavior is undefined.

7
добавлено

Этот кажется работает, но это неопределенное поведение . Просто случается, что в вашей конкретной реализации/платформе b берет последнее значение, возвращаемое из find . Однако на другой реализации/платформе это может также привести к сбою.

3
добавлено
Чтобы быть немного более конкретным: return a имеет побочный эффект настройки возвращаемого регистра, который не очищается. Но это неопределенное поведение , да
добавлено автор ckruse, источник

Предполагая, что вы намеревались написать find вместо trova (я знал, что когда-нибудь мне пригодится изучение итальянского языка :), ответ заключается в том, что это не работает отлично. Он «работает» исключительно случайно, в силу неопределенного поведения.

Скорее всего, самый глубокий рекурсивный вызов подталкивает возвращаемое значение в некоторый регистр, который вызовы более высокого уровня не касаются, потому что у них нет оператора return, и когда вызывающий абонент проверяет этот регистр, возвращаемое значение самого глубокого вызова все еще там. Однако вы не можете полагаться на это.

2
добавлено

Я не могу найти ссылку, но я помню, как много лет назад, в GCC, регистр возвращаемого значения (как выделено на CPU) всегда имел последнее возвращаемое значение, поэтому, если вы вычислили некоторое значение и возвращаете без значения, предыдущий ценность сохраняется. Похоже, плохая практика использует эту «особенность».

Возможно, см. Также

http://stackoverflow.com/questions/1610030/why-can-you -RETURN-с-а-непустая-функции-без возврата, а-значения-без пр

C: значение возврата по умолчанию, если значение не указано?

Это говорит: Uniballer 15 июня 2012 года, 01:44 Поведение не определено языком C, потому что вы не делали в функции то, что вы сказали, что собираетесь делать в объявлении функции. На практике, на x86 значение функции будет тем, что происходит в регистре eax при возврате.

1
добавлено
Удалите или обновите ссылки.
добавлено автор Pankaj Prakash, источник