без оператора возврата функция успешно выполнена

0

Я нашел этот код на каком-то сайте, что у него нет оператора возврата для возврата значения. Но на сайте это написано, так как оно дает ошибку времени компиляции. Хотя я пытался скомпилировать программу, чтобы узнать, какая ошибка будет видна в компиляторе. Программа скомпилирована с ошибкой.

Код c++:

int multiply(int x, int y)
{
  int product = x * y;
}

int main()
{
  cout << multiply(4, 5) << endl;
  return 0;
}

выход: 20

Теперь я смущен тем, что без какой-либо обратной инструкции, как компиляция прошла успешно.

  • 1
    Скомпилируйте две версии, одну с, другую без, инструкцию возврата. Запустите оба в отладчике и посмотрите на разборку перед каждым ret . То, что происходит, будет очевидно. Тем не менее, не полагайтесь на это.
  • 0
    включить все предупреждения ...
Показать ещё 3 комментария
Теги:

3 ответа

2

Без оператора return в функции этот код вызывал неопределенное поведение. Функция non void должна иметь оператор return.

С++ 11 § 6.6.3 Оператор возврата:

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

Как указано в комментарии WhozCraig, существует одно стандартное исключение из возвращаемого значения non-void, требующего return: int main()

С++ 11 § 3.6.1p5 [basic.start.main]

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

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

  • 0
    Привет, хак, я верю, что не void функция должна иметь оператор return. Но в приведенном выше коде функция выполнена успешно, без какого-либо оператора return, для которого я запутался ... :)
  • 2
    @ user1903535, прочитайте еще раз: неопределенное поведение .
Показать ещё 3 комментария
1

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

Вероятно, происходит то, что значение product все еще находится в стеке после выхода функции, и std::cout печатает это значение. Но опять же, не полагайтесь на неопределенное поведение.

  • 0
    Или (для большинства соглашений о вызовах x86) вычисление помещает свой результат в регистр eax , где вызывающая сторона ожидает возвращаемое значение.
1

Это неопределенное поведение, поэтому нет гарантии, что он будет работать.

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню