Временный объект уничтожается раньше ссылки на него
От: andrey_nado  
Дата: 03.05.11 14:16
Оценка: 9 (2)
Исходное сообщение (не моё) на StackOverflow. Я взял код оттуда и максимально его сократил:

#include <iostream>

struct foo {
    ~foo() {
        std::cout << "~foo()\n";
    }
};

struct foo_holder {
    const foo &f;
};

int main() {
    foo_holder holder = { foo() };
    std::cout << "done!\n";
    return 0;
}


После запуска программа печатает:

~foo()
done!


Вопрос: почему время жизни временного объекта в данном случае не продляется до времени жизни константной ссылки на него?
Компилятор gcc 4.3.2
c++ ссылка временный объект
Re: Временный объект уничтожается раньше ссылки на него
От: uzhas Ниоткуда  
Дата: 03.05.11 14:28
Оценка:
_>Вопрос: почему время жизни временного объекта в данном случае не продляется до времени жизни константной ссылки на него?
_>Компилятор gcc 4.3.2
потому что ссылка является мембером класса. тут продления не будет
время жизни продлевается только для ссылок на стеке (то бишь локальных ссылок) и ограничивается соответсвующим скоупом видимости
при выходе из скоупа объект разрушается
Re[2]: Временный объект уничтожается раньше ссылки на него
От: andrey_nado  
Дата: 03.05.11 14:38
Оценка:
Здравствуйте, uzhas, Вы писали:

U>потому что ссылка является мембером класса.


Но ведь ссылка — член автоматического объекта (который на стеке)? И на него распространяется правило 3.7.5/1:

The storage duration of member subobjects, base class subobjects and array elements is that of their complete
object (1.8).

Re[2]: Временный объект уничтожается раньше ссылки на него
От: dilmah США  
Дата: 03.05.11 14:42
Оценка:
U>потому что ссылка является мембером класса. тут продления не будет
U>время жизни продлевается только для ссылок на стеке (то бишь локальных ссылок) и ограничивается соответсвующим скоупом видимости
U>при выходе из скоупа объект разрушается

объект класса то тоже на стеке..
Re[3]: Временный объект уничтожается раньше ссылки на него
От: uzhas Ниоткуда  
Дата: 03.05.11 15:06
Оценка:
Здравствуйте, andrey_nado, Вы писали:

_>Здравствуйте, uzhas, Вы писали:


U>>потому что ссылка является мембером класса.


_>Но ведь ссылка — член автоматического объекта (который на стеке)? И на него распространяется правило 3.7.5/1:


тем не менее:

12.2 Temporary objects
4. There are two contexts in which temporaries are destroyed at a different point than the end of the fullexpression.
The first context is when an expression appears as an initializer for a declarator defining an
object
. In that context, the temporary that holds the result of the expression shall persist until the object’s
initialization is complete. The object is initialized from a copy of the temporary; during this copying, an
implementation can call the copy constructor many times; the temporary is destroyed after it has been
copied, before or when the initialization completes. If many temporaries are created by the evaluation of
the initializer, the temporaries are destroyed in reverse order of the completion of their construction.
191
ISO/IEC 14882:2003(E)  ISO/IEC
12.2 Temporary objects 12 Special member functions
5 The second context is when a reference is bound to a temporary. The temporary to which the reference is
bound or the temporary that is the complete object to a subobject of which the temporary is bound persists
for the lifetime of the reference except as specified below. A temporary bound to a reference member in a
constructor’s ctor-initializer (12.6.2) persists until the constructor exits. A temporary bound to a reference
parameter in a function call (5.2.2) persists until the completion of the full expression containing the call.
A temporary bound to the returned value in a function return statement (6.6.3) persists until the function
exits. In all these cases, the temporaries created during the evaluation of the expression initializing the reference,
except the temporary to which the reference is bound, are destroyed at the end of the full-expression
in which they are created and in the reverse order of the completion of their construction. If the lifetime of
two or more temporaries to which references are bound ends at the same point, these temporaries are
destroyed at that point in the reverse order of the completion of their construction. In addition, the
destruction of temporaries bound to references shall take into account the ordering of destruction of objects
with static or automatic storage duration (3.7.1, 3.7.2); that is, if obj1 is an object with static or automatic
storage duration created before the temporary is created, the temporary shall be destroyed before obj1 is
destroyed; if obj2 is an object with static or automatic storage duration created after the temporary is created,
the temporary shall be destroyed after obj2 is destroyed.


выделил вроде самое полезное, но остальное лучше тоже прочитать
Re[4]: Временный объект уничтожается раньше ссылки на него
От: andrey_nado  
Дата: 03.05.11 15:33
Оценка:
Здравствуйте, uzhas, Вы писали:

Если честно, не понял, как этот фрагмент стандарта относится к моему случаю. Разве что этим фрагментом: "A temporary bound to a reference member in a
constructor’s ctor-initializer (12.6.2) persists until the constructor exits."?

Вы цитируете стандарт C++03? В драфте нового стандарта этот пункт выглядит иначе и мой случай явно прописан, как рабочий (12.2.5):

A temporary bound to a reference in a new-initializer (5.3.4) persists until the completion of the
full-expression containing the new-initializer. [ Example:

struct S { int mi; const std::pair<int,int>& mp; };
S a { 1, {2,3} };
S* p = new S{ 1, {2,3} }; // Creates dangling reference


—end example ] [ Note: This may introduce a dangling reference, and implementations are encouraged
to issue a warning in such a case. —end note ]

Re[5]: Временный объект уничтожается раньше ссылки на него
От: uzhas Ниоткуда  
Дата: 03.05.11 16:18
Оценка:
Здравствуйте, andrey_nado, Вы писали:

_>Здравствуйте, uzhas, Вы писали:


_>Если честно, не понял, как этот фрагмент стандарта относится к моему случаю.

я выделил жирным то, что вроде относится к вашему случаю. а именно инициализация объекта другим временным объектом

_>Вы цитируете стандарт C++03? В драфте нового стандарта этот пункт выглядит иначе и мой случай явно прописан, как рабочий (12.2.5):

да, я процитировал C++03
по поводу драфта нового стандарта я с вами соглашусь — ссылки внутри агрегата могут продлить время жизни временного объекта, если это сделано мимо конструктора и без оператора new (то бишь все на стеке)
Re: Временный объект уничтожается раньше ссылки на него
От: Mr.Delphist  
Дата: 03.05.11 17:08
Оценка: :)
Здравствуйте, andrey_nado, Вы писали:

_>После запуска программа печатает:

_>
_>~foo()
_>done!
_>


А вы уверены, что компилятор не заинлайнил это до такого?
int main() {
    std::cout << "~foo()\n";
    std::cout << "done!\n";
    return 0;
}
Re[2]: Временный объект уничтожается раньше ссылки на него
От: uzhas Ниоткуда  
Дата: 03.05.11 17:26
Оценка:
Здравствуйте, Mr.Delphist, Вы писали:

MD>А вы уверены, что компилятор не заинлайнил это до такого?

это не имеет отношения к вопросу
заинлайнил он или нет — результат должен быть одинаковый и мы его пытаемся вычленить из стандарта
Re[6]: Временный объект уничтожается раньше ссылки на него
От: andrey_nado  
Дата: 03.05.11 19:25
Оценка:
Здравствуйте, uzhas, Вы писали:

U>я выделил жирным то, что вроде относится к вашему случаю. а именно инициализация объекта другим временным объектом


> 12.2 Temporary objects

4. There are two contexts in which temporaries are destroyed at a different point than the end of the fullexpression.

Что тогда означает это "at different point". Не означает ли это, что уничтожение временного объекта должно быть отложено? А если мой случай подпадает под эти самые "two contexts", но и уничтожение должно быть отложено в моём случае? Как Вы считаете?
Re[2]: Временный объект уничтожается раньше ссылки на него
От: andrey_nado  
Дата: 03.05.11 19:30
Оценка:
Здравствуйте, Mr.Delphist, Вы писали:

MD>А вы уверены, что компилятор не заинлайнил это до такого?


Это не важно. Временный объект действительно уничтожается до использования объекта holder в функции main, это несложно проверить дополнительной трассировкой.
Re: Временный объект уничтожается раньше ссылки на него
От: Masterkent  
Дата: 03.05.11 20:04
Оценка:
andrey_nado:

_>После запуска программа печатает:


_>
_>~foo()
_>done!
_>


_>Вопрос: почему время жизни временного объекта в данном случае не продляется до времени жизни константной ссылки на него?

_>Компилятор gcc 4.3.2

Баг gcc. У меня в 4.7.0 то же самое. Он и вот такой код

#include <iostream>

struct X
{
    ~X()
    {
        std::cout << "~X()\n";
    }
};

struct Y {
    Y() : ref(X()) { std::cout << "Y()\n"; }
    X const &ref;
};

int main()
{
    Y y;
}

не умеет правильно компилить. Intel C++ 12.0, как и положено, выводит:

done!
~foo()

и

Y()
~X()

соответственно.
Re[2]: Временный объект уничтожается раньше ссылки на него
От: uzhas Ниоткуда  
Дата: 04.05.11 05:13
Оценка:
Здравствуйте, Masterkent, Вы писали:

M>Баг gcc.

расскажите, пожалуйста, как это вывести из стандарта и изменилось ли что-то в драфте? изменилась ли формулировка на более ясную или мутную?
я иду по классическому пути "гляжу в книгу — вижу фигу"
Re[3]: Временный объект уничтожается раньше ссылки на него
От: Masterkent  
Дата: 04.05.11 06:00
Оценка: 26 (2)
uzhas:

U>как это вывести из стандарта и изменилось ли что-то в драфте?


С++03, N3290 — 12.2/5:

The temporary to which the reference is bound or the temporary that is the complete object to a subobject of which the temporary is bound persists for the lifetime of the reference except as specified below.

Исключения, перечисленные ниже, не подходят (что в C++03, что в C++0x).

U> изменилась ли формулировка на более ясную или мутную?


Как была плохая, так и осталась.

#include <iostream>

struct X
{
    X() { std::cout << "X()\n"; }
    ~X() { std::cout << "~X()\n"; }
};

struct T
{
    T(X const &) {}
};

void f(X const &) {}

void g()
{
    std::cout << "f()\n";
}

int main()
{
    ( f(X()), g() ); // время жизни временного объекта типа X - full-expression
    ( T(X()), g() ); // должно быть аналогично предыдущему, но в правилах это не прописано
}
Re[2]: Временный объект уничтожается раньше ссылки на него
От: andrey_nado  
Дата: 04.05.11 07:52
Оценка:
Здравствуйте, Masterkent, Вы писали:

Я посмотрел в MS Visual Studio C++ 2008, там результат такой же, как в gcc!
Re[3]: Временный объект уничтожается раньше ссылки на него
От: ononim  
Дата: 04.05.11 08:42
Оценка:
_>Но ведь ссылка — член автоматического объекта (который на стеке)? И на него распространяется правило 3.7.5/1:
_>

The storage duration of member subobjects, base class subobjects and array elements is that of their complete
_>object (1.8).

Дык ссылка осталась. Не осталось объекта на который она ссылается. Так что процитированное вами не нарушается.
Как много веселых ребят, и все делают велосипед...
Re[4]: Временный объект уничтожается раньше ссылки на него
От: andrey_nado  
Дата: 04.05.11 10:18
Оценка:
Здравствуйте, ononim, Вы писали:

O>Дык ссылка осталась. Не осталось объекта на который она ссылается. Так что процитированное вами не нарушается.


Вопрос, почему временный объект уничтожается раньше. Какой параграф стандарта декларирует или допускает такое поведение?
Re[5]: Временный объект уничтожается раньше ссылки на него
От: ononim  
Дата: 04.05.11 10:24
Оценка: :)
O>>Дык ссылка осталась. Не осталось объекта на который она ссылается. Так что процитированное вами не нарушается.
_>Вопрос, почему временный объект уничтожается раньше. Какой параграф стандарта декларирует или допускает такое поведение?
Временный объект уничтожается когда ему полагается, какие параграфы не помню, но думаю вы сами найдете, ссылка на время его жизни не влияет.
Ссылка продлевает время жизни временного объекта наскока я знаю тока в одном случае, вот в таком:
Foo GetFoo()
{
Foo f;
return f;
}
const Foo &const_ref_to_f = GetFoo();

и это продление описано в стандарте, так что если для вашего случае не описано продление времени жизни объекта — оно и не будет продлено.
Как много веселых ребят, и все делают велосипед...
Re: Временный объект уничтожается раньше ссылки на него
От: MasterZiv СССР  
Дата: 05.05.11 05:23
Оценка: +1 -1
On 03.05.2011 18:16, andrey_nado wrote:

> Вопрос: почему время жизни временного объекта в данном случае не продляется до

> времени жизни константной ссылки на него?

Э, молодой человек, если бы этот код работал, в С++ были бы замыкания.
Posted via RSDN NNTP Server 2.1 beta
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.