Вопрос:

Как проги C ++ получают свое возвращаемое значение, если в функции не указано возвращаемое значение?

c++ memory return-value return

987 просмотра

6 ответа

2747 Репутация автора

Недавно я написал сообщение: «
Странная ошибка в программе на 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 Источник Размещён: 11.08.2010 03:06

Ответы (6)


5 плюса

88710 Репутация автора

В этом нет логики, и большинство компиляторов C ++ должны пометить это предупреждением. Это позволило для обратной совместимости с C.

В K & R C не было voidтипа, а когда тип не был указан, по умолчанию используется значение int. Так,

myfunc() {....}

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

Компилятор должен был понять это. Таким образом, конвенция стала, что- returnто положить в реестр. И присваивание в вызывающей подпрограмме вывело бы значение из регистра. Теперь, если вызываемый никогда не выдавал возврат, ничего конкретного не было бы помещено в этот регистр. Но он все равно будет иметь некоторое (случайное) значение, которое будет слепо назначено вызывающей стороне.

Автор: James Curran Размещён: 11.08.2010 03:11

1 плюс

2345 Репутация автора

Это зависит от соглашения о вызовах. Например, для возврата 32-разрядного целого на платформе Intel вы получаете все, что есть в eaxреестре.

Автор: grddev Размещён: 11.08.2010 03:12

4 плюса

6222 Репутация автора

Из раздела C ++ Standard 6.6.3 Оператор возврата

Выпуск из конца функции эквивалентен возврату без значения; это приводит к неопределенному поведению в функции, возвращающей значение.

Есть одно исключение (согласно 3.6.1 / 5):

Если управление достигает конца main, не встречая оператора return, результатом является выполнение return 0;

Причина, по которой это синтаксически разрешено, хорошо описана Джеймсом Керраном . Но с опцией -Wall gcc (как прокомментировал Нил) вы должны быть предупреждены об этом поведении; что-то вроде «Не все пути управления возвращают значение в функции, возвращающей значение ...».

Автор: Abhay Размещён: 11.08.2010 03:14

5 плюса

3201 Репутация автора

Решение

В соглашениях о вызовах x86 возвращаемое значение для целых чисел и указателей находится в регистре EAX. Ниже приведен пример этого:

int func() {
    if(0) return 5; // otherwise error C4716: 'func' : must return a value
}
int main() {
    int a;
    a = func();
}

Компиляция с cl.exe /ZiMSVC ++ 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:18

0 плюса

2395 Репутация автора

С современным компилятором вы, вероятно, получите предупреждение, используя -Wall

Но если вы не вернете значение, вы получите мусор.

Автор: ppaulojr Размещён: 11.08.2010 03:24

0 плюса

2038 Репутация автора

«Что определяет, что функция 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
Вопросы из категории :
32x32