Вопрос по c – Неявное int возвращаемое значение функции C

22

Я гуглил и, похоже, просто не могу найти ответ на этот простой вопрос.

Работая над устаревшей кодовой базой (недавно портированной на Linux и медленно обновляющейся до нового компилятора), и я вижу много

<code>int myfunction(...)
{
// no return...
}
</code>

Я знаю, что неявный возврат TYPE функции является int, но что такое неявное возвращаемое значение VALUE, когда не указан возврат. Я проверил и получил 0, но это только с gcc. Этот компилятор специфичен или стандартно равен 0?

РЕДАКТИРОВАТЬ: 12/2017 Скорректированный принятый ответ основан на том, что он ссылается на более свежую версию стандарта.

& quot; неявный возвращаемый тип & quot; был удален в C99 M.M
Принятый ответ должен быть изменен. Цитирование 89 версии стандарта в 2016 году неуместно. Antti Haapala
попробуйте скомпилировать с -Wall -O3 и без -g. Попытайтесь увидеть, является ли возвращаемое значение все еще 0 и существует ли какое-либо предупреждение kappa
Действительно старый школьный код имеет тенденцию смешивать ассемблерный и C-код. В некоторых случаях код сборки будет устанавливать возвращаемое значение. Обязательно проверьте, присутствует ли какой-либо ассемблерный код, используя ключевое слово extern или _asm. Dan
Попробуй скомпилировать с-Wall -Werror и посмотреть, если он все еще компилируется. dreamlax

Ваш Ответ

7   ответов
10

если вы не заполняете область возврата (которая, например, обычноeax / rax на процессорах семейства x86), это значение будет установлено последним через какой-либо побочный эффект в вашей функции.

УвидетьЯвляется ли оператор return обязательным для функций C ++, которые не возвращают void? который в основном дублирует этот вопрос (за исключением того, что он помечен как C ++).

да, это не неопределенное поведение, если вы не прочитали возвращаемое значение. Смотри мой ответ.
Не совсем, это только UB, если используется возвращаемое значение, что, вероятно, здесь не так, смотрите мой ответ.
2

Еслиreturn операторы последовательно не возвращают значение, функцию лучше всего преобразовать в и объявить как возвращающуюvoid:

void myfunction(...)
{
    ...
    return;
    ...
}

Если есть некоторыеreturn expr; и немногоreturn; операторы в функции, то вам нужно решить, какое поведение лучше, и сделать их согласованными & # x2014; либо всегда возвращайте значение и оставляйте тип какint или никогда не возвращать значение и изменить тип наvoid.

Обратите внимание, что вам нужно объявить функции, измененные для возвратаvoid (в заголовке, если они не являются & # x2014; или должны быть & # x2014;static и скрыты в одном исходном файле), поскольку тип возвращаемого по умолчанию (предполагаемый тип возвращаемого значения)int больше не действителен

7

даже если тип возвращаемого значения функции не являетсяvoid, Диагностика не требуется, и это не неопределенное поведение.

Пример (определенное поведение):

int foo(void)
{
}

int main()
{
    foo();
}

Но читая возвращаемое значениеfoo является неопределенным поведением:

int bla = foo();  // undefined behavior

Из стандарта С:

(C99, 6.9.1p12) "If the } that terminates a function is reached, and the value of the function call is used by the caller, the behavior is undefined."

main Функция является исключением из этого правила, как будто} достигается вmain это эквивалентно, как если быreturn 0; заявление.

"and it is not undefined behavior" если вызывающая сторона не использует возвращаемое значение.
@ouah Можем ли мы сделать это в cpp?
@dmckee, вот почему я написал:"But reading the return value of foo is undefined behavior"
0

что это неопределенное поведение для функции, тип возвращаемой которой неvoid опуститьreturn заявление. В C99 есть исключение дляmainгде, еслиreturn оператор не указан, предполагается, что он возвращает 0 неявно, но это не относится к любой другой функции.

Он может работать на определенной комбинации платформы / компилятора, но вы никогда не должны полагаться на такие особенности. Использование любого неопределенного поведения в вашем коде делает его непереносимым. Однако часто встречается неопределенное поведение в устаревшем коде.

8

но только при условии, что возвращаемое значение функции никогда не используется. Стандарт C11 говорит в параграфе 6.9.1:

If the } that terminates a function is reached, and the value of the function call is used by the caller, the behavior is undefined.

(AFAIR предыдущая версия стандарта имела похожую формулировку)

Так что было бы неплохо преобразовать все функции такого рода, которые вы должныvoid функции, поэтому ни у одного пользователя такой функции не может возникнуть соблазн использовать возвращаемое значение.

@Pacerier, нет, я не думаю, что это так, и в ответе о том же сказано то же самое.
Да, стандарт говорит это.
Хорошо, ты говоришь, чтоas long as we don't read it, поведение программы все еще в порядке?
Ну, первый ответ от dmckee, кажется, противоречит этому.
21

Flowing off the end of a function is equivalent to a return with no expression. In either case, the return value is undefined.

Этот стандарт обычно выражает практическое поведение уже существующих реализаций.

Ну, как цитирует Йенс, этот стандарт, похоже, гарантирует хорошее поведение, если вы не используете неопределенное возвращаемое значение.
Стандарт 89 не указывает. Я бы предположил, что фактические компиляторы не доставят вам сюрпризов, если вы не попытаетесь использовать возвращаемое значение. Но никто не гарантирует этого.
Вы имеете в виду, что только значение не определено или что поведение программы после этой точки не определено?
Какиеabout C11 затем?
@Pacerier это просто означает, что значение не определено. Поведение программы все еще будет определено, но любое выражение, которое использует это значение, будет неопределенным.
1

но в большинстве архитектур (конечно, в x86) оператор return перемещает содержимое определенного регистра в определенное место в стеке, которое вызывающая сторона будет извлекать и использовать в качестве своей функции возврата.

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

Похожие вопросы