Временное продление жизни

Раздел 12.2.5 стандарта гласит:

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

Код, который я пытаюсь понять:

#include <iostream>

const int& foo(const int& fooRef)
{
    return fooRef;
}                                        // #0

int main (void)
{
    const int& numberRef = foo(5);     // #1
    std::cout << numberRef;            // #2
    return 0;
}

Онлайн #1 временный объект создан и привязан к fooRef параметр foo, fooRef уничтожен на линии #0, Поэтому я подумал, что временное должно быть уничтожено здесь, поскольку продление жизни не является транзитивным.

Вопросы:

  1. Что значит until the function exits имею в виду? Значит ли это untill it finished executing?

  2. Почему я получаю 5 выход. Временный объект все еще существует на линии #2?

  3. Как я могу интерпретировать стандартную цитату, чтобы понять, как работает этот пример?

Пошаговое пошаговое ознакомление с атомными стандартами и ссылками на стандарт. Спасибо!

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

2 ответа

Решение

Что значит до выхода из функции? Означает ли это, пока не закончится выполнение?

Да.

Почему я получаю 5 выходных. Временный объект все еще существует в строке #2?

Разыменование ссылки, которая не связана с живым объектом, является неопределенным поведением, поэтому вы можете получить 5 так же как 42 как и все остальное (включая аварию). Вы просто не можете ожидать каких-либо ожиданий от программы с неопределенным поведением.

Как я могу интерпретировать стандартную цитату, чтобы понять, как работает этот пример?

В значительной степени, как вы уже сделали. Временная привязка к параметру функции fooRef, который разрушается при возврате из функции. Поскольку этот временный объект связан с возвращаемым значением, этот объект перестает существовать, когда функция возвращается. Позже вы разыменовываете свисающую ссылку, которая дает вам UB.

  1. Значит до закрывающей скобки, т.е. },

  2. Вы вызвали UB, у вас есть свисающая ссылка.

Попробуйте следующую модификацию вашего кода и посмотрите, что он печатает. Это вероятно напечатает 6 потому что это то, что было последним в стеке. Или попробуйте передать std::string вместо этого вы можете получить сбой.

int main (void)
{
    const int& numberRef = foo(5);  
    foo(6);
    std::cout << numberRef;
    return 0;
}
Другие вопросы по тегам