Как проги C ++ получают свое возвращаемое значение, если в функции не указано возвращаемое значение?
987 просмотра
6 ответа
Недавно я написал сообщение: «
Странная ошибка в программе на C ++: удаление программы для прерывания печати»
... в котором я пытался решить, казалось бы, непонятную проблему, в которой удаление оператора cout сломало бы мою программу.
Как выяснилось, моя проблема заключалась в том, что я забыл вернуть свой флаг истинного / ложного успеха, который позже использовал для логики.
Но, видимо, ЧТО-ТО возвращалось, и что-то всегда было правдой, если бы я оставил этот кут, но, казалось бы, «волшебным образом» стало бы ложным, когда я его вынул.
Мой вопрос ко всем вам:
что определяет, что возвращает функция с ++, если в функции не выполняется команда возврата? Есть ли в этом логика?
Очевидно, что забывать свой тип возврата - плохая идея. В этом случае, тем не менее, это было во многом из-за характера моей программы - быстрой взломать работу. Позже я решил, что не стоит тратить усилия на реализацию алгоритма, определяющего успех / неудачу вызова функции, - но случайно оставил код, зависящий от возврата.
Удивительно g ++ не дал мне никаких предупреждений или ошибок при компиляции исполняемого файла следующим образом:
g++ main.cc -g -o it_util
Моя версия: g ++ (GCC) 4.1.2 20080704 (Red Hat 4.1.2-44)
Опять же, чтобы спасти других от разочарования в будущем, если они совершат ту же глупую ошибку и столкнутся с тем же, казалось бы, ошибочным поведением, может ли кто-нибудь пролить свет на то, откуда функция без возврата получает свое возвращаемое значение ??
Спасибо!!
Автор: Jason R. Mick Источник Размещён: 13.11.2019 11:47Ответы (6)
5 плюса
В соглашениях о вызовах x86 возвращаемое значение для целых чисел и указателей находится в регистре EAX. Ниже приведен пример этого:
int func() {
if(0) return 5; // otherwise error C4716: 'func' : must return a value
}
int main() {
int a;
a = func();
}
Компиляция с cl.exe /Zi
MSVC ++ 10:
push ebp
mov ebp, esp
push ecx
call j_?func@@YAHXZ ; func(void)
mov [ebp+a], eax ; assumes eax contains the return value
xor eax, eax
mov esp, ebp
pop ebp
retn
Конечно, это все неопределенное поведение.
Автор: Pedro d'Aquino Размещён: 11.08.2010 03:185 плюса
В этом нет логики, и большинство компиляторов C ++ должны пометить это предупреждением. Это позволило для обратной совместимости с C.
В K & R C не было void
типа, а когда тип не был указан, по умолчанию используется значение int
. Так,
myfunc() {....}
Технически это была функция, возвращающая int, но большинство программистов использовали эту форму для подпрограммы, не возвращающей значение.
Компилятор должен был понять это. Таким образом, конвенция стала, что- return
то положить в реестр. И присваивание в вызывающей подпрограмме вывело бы значение из регистра. Теперь, если вызываемый никогда не выдавал возврат, ничего конкретного не было бы помещено в этот регистр. Но он все равно будет иметь некоторое (случайное) значение, которое будет слепо назначено вызывающей стороне.
4 плюса
Из раздела C ++ Standard 6.6.3 Оператор возврата
Выпуск из конца функции эквивалентен возврату без значения; это приводит к неопределенному поведению в функции, возвращающей значение.
Есть одно исключение (согласно 3.6.1 / 5):
Если управление достигает конца main, не встречая оператора return, результатом является выполнение return 0;
Причина, по которой это синтаксически разрешено, хорошо описана Джеймсом Керраном . Но с опцией -Wall gcc (как прокомментировал Нил) вы должны быть предупреждены об этом поведении; что-то вроде «Не все пути управления возвращают значение в функции, возвращающей значение ...».
Автор: Abhay Размещён: 11.08.2010 03:141 плюс
Это зависит от соглашения о вызовах. Например, для возврата 32-разрядного целого на платформе Intel вы получаете все, что есть в eax
реестре.
0 плюса
С современным компилятором вы, вероятно, получите предупреждение, используя -Wall
Но если вы не вернете значение, вы получите мусор.
Автор: ppaulojr Размещён: 11.08.2010 03:240 плюса
«Что определяет, что функция c ++ возвращает, когда в функции не выполняется команда возврата? Есть ли какая-то логика?»
Тип в начале функции.
Пример:
int cow () {int temp; вернуть темп; }
Если вы не вернете правильный тип или ничего не вернете, компилятор должен пожаловаться. Изменить: О дерьмо, я только что прочитал ваши флаги. Вам нужно включить больше флагов, -W -Wall -Pedantic. Прочтите руководство по g ++.
Если у вас нет функции void. Тогда вам не нужно ничего возвращать, или вы можете иметь указатель для игры.
void somefunction (int * ptr_int) {int temp = * ptr_int; температура + = 1000; this-> ptr_int = temp; }
Я считаю, что приведенный выше код работает, прошло некоторое время с тех пор, как я написал код на C ++.
Автор: mythicalprogrammer Размещён: 11.08.2010 03:56Вопросы из категории :
- c++ What are the barriers to understanding pointers and what can be done to overcome them?
- c++ Какой самый простой способ для анализа файла INI в C ++?
- c++ Когда вы должны использовать «друг» в C ++?
- c++ Как вы очищаете переменную stringstream?
- c++ В C ++ конструктор и деструктор могут быть встроенными функциями?
- memory Setting Objects to Null/Nothing after use in .NET
- memory Предотвращение утечек памяти с прикрепленным поведением
- memory CLR Profiler - Присоединение к существующему процессу
- memory Как определить размер моего массива в C?
- memory В Java, как лучше всего определить размер объекта?
- return-value Что должно возвращать main () в C и C ++?
- return-value Как вернуть несколько значений из функции?
- return-value Как сделать метод, возвращающий тип, универсальным?
- return-value Как вызвать внешнюю программу на python и получить выходной код и код возврата?
- return-value Это хороший стиль, чтобы явно вернуться в Ruby?
- return Какой лучший способ вернуть несколько значений из функции в Python?
- return Возвращаясь из блока finally в Java
- return Всегда ли выполняется блок finally в Java?
- return Проверка кодов возврата ftp из сценария Unix