Как известно, если rvalue передаётся в некую функцию через константную ссылку, то время его жизни продлевается. Т. е. в следующем примере оно точно живёт пока выполняется функция ref_to_ptr. Вопрос в том, насколько долго обязано жить такое значение и допустимо ли его использование в функции print, либо же это UB с разыменованием потенциально мусорного указателя?
https://ideone.com/CcacHz
#include
using namespace std;
template
void print(const int *val)
{
cout << *val << endl;
}
int main()
{
print(ref_to_ptr(42));
return 0;
}
Ответ
Насколько я понимаю стандарт (цитата):
⁴ [...] Temporary objects are destroyed as the last step in evaluating the full-expression that (lexically) contains the point where they were created. [...]
⁵ There are three contexts in which temporaries are destroyed at a different point than the end of the full-expression. [...]
⁶ The third context is when a reference is bound to a temporary object.
The temporary object to which the reference is bound or the temporary object that is the complete object of a subobject to which the reference is bound persists for the lifetime of the reference [...]
The exceptions to this lifetime rule are:
(6.9) — A temporary object bound to a reference parameter in a function call persists until the completion of the full-expression containing the call.
(6.10) — The lifetime of a temporary bound to the returned value in a function return statement is not extended; the temporary is destroyed at the end of the full-expression in the return statement.
Иными словами: обычно временный объект, на который ссылается ссылка, умирает вместе со ссылкой. Но если вы передаёте в функцию временный объект как аргумент для ref-параметра, время жизни этого временного объекта продлевается до конца всего выражения, содержащего вызов функции.
Это значит, что время жизни параметра x заканчивается в конце строки
print(ref_to_ptr(42));
то есть доступа к «умершему» объекту нет.
Это также, судя по всему, означает, что переписав код следующим образом:
const int *ptr = ref_to_ptr(42);
print(ptr);
вы получите таки undefined behaviour, т. к. время жизни временного объекта, на который указывает ptr, заканчивается после первой строки!
Комментариев нет:
Отправить комментарий