каково возвращаемое значение функции, которая возвращает int, но ничего не возвращает явно. например, вывод из

#c #compiler-construction #stack #stack-trace

#c #компилятор-конструкция #стек #трассировка стека

Вопрос:

 int fun()
{
 printf("ncrap");
}


void main()
{
  printf("n return value of fun %d", fun());
}
  

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

Комментарии:

1. Я знаю, что это зависит от архитектуры, но я прошу об общем.

Ответ №1:

fun вызывает неопределенное поведение.

Пожалуйста, всегда компилируйте со всеми включенными предупреждениями компилятора. Это должно выдать вам предупреждение о том, что вы совершаете ту самую ошибку.

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

«Стек», как вы предполагаете, не является частью языка C . Но это не имеет значения; стандарт гласит, что возвращаемый объект создается в области вызывающего, и это все, что вам нужно знать.

(Практически, невозвращенная int , вероятно, закончится как неинициализированная переменная типа int , но стандарт гласит, что вызов функции уже запускает неопределенное поведение, а не просто доступ для чтения позже.)

Комментарии:

1. Нет, всегда компилируйте с включенными некоторыми предупреждениями компилятора. Включая это 😉 (хотя 1)

2. Итак, вы имеете в виду, что все может быть напечатано ??… С помощью -Wall он выдает предупреждение… Но мне любопытно узнать о стеке… Я имею в виду, что хранится в стеке??

3. @Invictus: Ну, поскольку %d означает «тип int «, я полагаю, да, может быть напечатано любое целое значение . «Неопределенное поведение» фактически означает, что программа может вести себя любым образом (сбой, форматирование вашего жесткого диска, заказ пиццы). Практически, хотя я полагаю, вы всегда доберетесь до printf строки. Майкл: Я имел в виду что-то вроде -Wall ; не обязательно «все неясные и сомнительные предупреждения». Краткость — душа nit, не так ли?

Ответ №2:

Это неопределенное поведение. Может произойти все, что угодно.

Ответ №3:

Поскольку это зависит от архитектуры, общего понятия не существует.

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

Обратите также внимание, что для int main() существует особый случай. (Кстати: void main() не является стандартным.) Если оператор return не присутствует, он возвращает 0 .