Re[6]: возврат ссылки на переданные по ссылке данные в функц
От: Alexander G Украина  
Дата: 15.01.09 23:20
Оценка: 6 (1)
Здравствуйте, Vamp, Вы писали:

AG>>Продлевать может только константная ссылка, привязанная на временный объект.

V>Что мы и имеем в приведенном примере.

А давай попробуем:

struct triple
{
  triple(int) { printf("ctor\n"); }
  triple(triple const&) { printf("cctor\n"); }
  ~triple() { printf("dtor\n"); }
};

triple const& foo(triple const& rd){
 return rd;
}
int main () {
 triple& r = foo(5 + 10);
 printf("r is NOT valid");
}


не компилируется, добавляем const, получаем, как и ожидалось "r is NOT valid" уже после "dtor\n".
Русский военный корабль идёт ко дну!
Re[2]: возврат ссылки на переданные по ссылке данные в функц
От: Аноним  
Дата: 16.01.09 07:50
Оценка: 6 (1)
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Аноним, Вы писали:


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

вот примерyj так



const int &foo(const int &ri)
{
  return ri;
}

const int &bar(const int &ri)
{
  static int stub
  return stub;
}

int main()
{
  const int &ri1 = foo(10+2);//вроде как можно б и продлить..
  const int &ri2 = bar(10+2);//100% нельзя продливать
Re[8]: возврат ссылки на переданные по ссылке данные в функц
От: Vain Россия google.ru
Дата: 16.01.09 09:32
Оценка: 3 (1)
Здравствуйте, rg45, Вы писали:

AG>>не компилируется, добавляем const, получаем, как и ожидалось "r is NOT valid" уже после "dtor\n".

R>Так, я запутался... Как тогда понимать 12.2/5
Строчка

except the temporary to which the reference is bound

должна быть несколько, имхо, перефразирована где-то так:

except the temporary to which the reference is already bound

Имеется ввиду что expression разрушает объект, если в нём он и создался, а это может быть только, если он исходно передан не по ссылке.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[7]: возврат ссылки на переданные по ссылке данные в функц
От: Юрий Жмеренецкий ICQ 380412032
Дата: 16.01.09 13:37
Оценка: 3 (1)
Здравствуйте, rg45, Вы писали:

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


V>>Это не важно. У нас тут получается длинная цепочка ссылок на временные объект, который будет жить до тех пор, пока живет хотя бы одна из них.


R>Все-таки, склоняюсь к мысли, что это неверное утверждение. Формулировка в стандарте выглядит недостаточно четкой.

Я это понимаю так:
const int &foo(const int &i) { return i; }

int main()
{
  const int &ri1 = foo(1);
}


При инициализации 'ri1' ссылка будет связана непосредственно с initializer expression lvalue (результат 'foo(...)'). На этом этапе [в нашем случае] никаких временных объектов не создается(8.5.3/5), поэтому и продлевать жизнь нечему.

Тем не менее, в initializer expression, только к таким (опционально полученным при связывании) временным объектам применимо продление жизни (12.2/4) в обсуждаемом контексте.

Все что описывает 12.2/5 ('The second context...') сюда не относится. Но относится к временному объекту, созданному при связывании параметра функции 'foo' и, соответственно, 'ri1' после инициализации ссылается на мусор).
Re[5]: возврат ссылки на переданные по ссылке данные в функц
От: Vamp Россия  
Дата: 15.01.09 22:44
Оценка: -1
R>Э нет. Одно дело, когда функция возвращает результат по значению, тогда время жизни этого временного объекта можно продлить константной ссылкой. Совсем другое дело, когда функция возвращает ссылку на объект, время жизни которого заканчивается после выхода из функции.
Это не важно. У нас тут получается длинная цепочка ссылок на временные объект, который будет жить до тех пор, пока живет хотя бы одна из них.
Да здравствует мыло душистое и веревка пушистая.
Re[8]: возврат ссылки на переданные по ссылке данные в функц
От: Юрий Жмеренецкий ICQ 380412032
Дата: 16.01.09 14:08
Оценка: :)
Здравствуйте, Юрий Жмеренецкий, Вы писали:
...
ЮЖ>Тем не менее, в initializer expression, только к таким (опционально полученным при связывании) временным объектам применимо продление жизни (12.2/4) в обсуждаемом контексте.
Это надо выкинуть.
возврат ссылки на переданные по ссылке данные в функцию..
От: Аноним  
Дата: 15.01.09 21:24
Оценка:
эмм безопасен ли вот такой код?

int i;
double const& foo(double const& rd){
  return rd;
}

double d = foo(static_cast<double>(i));


правильно ли я понимаю, что фунция foo получает ссылку на временный объект типа double, и в дальнейшем ее же вовзвращает, поэтому дальнейшие операции с ней не корректны?
Re: возврат ссылки на переданные по ссылке данные в функцию.
От: Vamp Россия  
Дата: 15.01.09 21:41
Оценка:
В общем случае небезопасен.
Пример:

double const& foo(double const& rd){
return rd;
}

int main () {
double* pd = new double(10);

double& r = foo(*pd);

delete pd; //r более не валидна
}

Но зачастую безопасен:

int main () {
double& r = foo(5 + 10);
//r валидна вполне
}
Да здравствует мыло душистое и веревка пушистая.
Re[2]: возврат ссылки на переданные по ссылке данные в функц
От: Alexander G Украина  
Дата: 15.01.09 22:11
Оценка:
Здравствуйте, Vamp, Вы писали:

V>double const& foo(double const& rd){

V> return rd;
V>}
V>int main () {
V> double& r = foo(5 + 10);
V> //r валидна вполне
V>}

Почему валидна?
Русский военный корабль идёт ко дну!
Re[3]: возврат ссылки на переданные по ссылке данные в функц
От: Vamp Россия  
Дата: 15.01.09 22:12
Оценка:
AG>Почему валидна?
Потому, что время жизни временного объекта, к которому привязана ссылка, продлевается до тех пор, пока жива ссылка на него.
Да здравствует мыло душистое и веревка пушистая.
Re[4]: возврат ссылки на переданные по ссылке данные в функц
От: rg45 СССР  
Дата: 15.01.09 22:41
Оценка:
Здравствуйте, Vamp, Вы писали:

AG>>Почему валидна?

V>Потому, что время жизни временного объекта, к которому привязана ссылка, продлевается до тех пор, пока жива ссылка на него.

Э нет. Одно дело, когда функция возвращает результат по значению, тогда время жизни этого временного объекта можно продлить константной ссылкой. Совсем другое дело, когда функция возвращает ссылку на объект, время жизни которого заканчивается после выхода из функции.
--
Справедливость выше закона. А человечность выше справедливости.
Re[4]: возврат ссылки на переданные по ссылке данные в функц
От: Alexander G Украина  
Дата: 15.01.09 22:44
Оценка:
Здравствуйте, Vamp, Вы писали:

V>Потому, что время жизни временного объекта, к которому привязана ссылка, продлевается до тех пор, пока жива ссылка на него.


А какое отношение ссылка в параметре имеет к ссылке double& r ?
Продлевать может только константная ссылка, привязанная на временный объект.
(расширения MSVC в рассчёт не берём, хотя тут даже они не помогут)
Русский военный корабль идёт ко дну!
Re: возврат ссылки на переданные по ссылке данные в функцию.
От: Alexander G Украина  
Дата: 15.01.09 22:49
Оценка:
Здравствуйте, Аноним, Вы писали:

А>
А>int i;
А>double const& foo(double const& rd){
А>  return rd;
А>}

А>double d = foo(static_cast<double>(i));
А>


А>правильно ли я понимаю, что фунция foo получает ссылку на временный объект типа double, и в дальнейшем ее же вовзвращает, поэтому дальнейшие операции с ней не корректны?


Код безопасен, временный объект типа double создался вне функции foo, здесь:
double d = foo(static_cast<double>(i));
, поэтому разрушен будет в конце здесь
double d = foo(static_cast<double>(i));
Русский военный корабль идёт ко дну!
Re[5]: возврат ссылки на переданные по ссылке данные в функц
От: Vamp Россия  
Дата: 15.01.09 22:54
Оценка:
AG>Продлевать может только константная ссылка, привязанная на временный объект.
Что мы и имеем в приведенном примере.
Да здравствует мыло душистое и веревка пушистая.
Re[6]: возврат ссылки на переданные по ссылке данные в функц
От: rg45 СССР  
Дата: 15.01.09 23:13
Оценка:
Здравствуйте, Vamp, Вы писали:

R>>Э нет. Одно дело, когда функция возвращает результат по значению, тогда время жизни этого временного объекта можно продлить константной ссылкой. Совсем другое дело, когда функция возвращает ссылку на объект, время жизни которого заканчивается после выхода из функции.

V>Это не важно. У нас тут получается длинная цепочка ссылок на временные объект, который будет жить до тех пор, пока живет хотя бы одна из них.

Похоже, что действительно так.

12.2/5
...
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.
...

Оно?
--
Справедливость выше закона. А человечность выше справедливости.
Re[7]: возврат ссылки на переданные по ссылке данные в функц
От: rg45 СССР  
Дата: 15.01.09 23:38
Оценка:
Здравствуйте, Alexander G, Вы писали:

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


AG>>>Продлевать может только константная ссылка, привязанная на временный объект.

V>>Что мы и имеем в приведенном примере.

AG>А давай попробуем:


AG>
AG>struct triple
AG>{
AG>  triple(int) { printf("ctor\n"); }
AG>  triple(triple const&) { printf("cctor\n"); }
AG>  ~triple() { printf("dtor\n"); }
AG>};

AG>triple const& foo(triple const& rd){
AG> return rd;
AG>}
AG>int main () {
AG> triple& r = foo(5 + 10);
AG> printf("r is NOT valid");
AG>}
AG>


AG>не компилируется, добавляем const, получаем, как и ожидалось "r is NOT valid" уже после "dtor\n".


Так, я запутался... Как тогда понимать 12.2/5
--
Справедливость выше закона. А человечность выше справедливости.
Re[8]: возврат ссылки на переданные по ссылке данные в функц
От: Alexander G Украина  
Дата: 15.01.09 23:47
Оценка:
Здравствуйте, rg45, Вы писали:

R>Так, я запутался... Как тогда понимать 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 per-
sists for the lifetime of the reference or until the end of the scope
in which the temporary is created, whichever comes first.


Я это понимаю, что речь об именно той ссылке, которая инициализирована временным объектом.

Здесь мы в этом случае:

A temporary bound to a reference parameter in
a function call persists until the completion of the
full expression containing the call
.

Русский военный корабль идёт ко дну!
Re: возврат ссылки на переданные по ссылке данные в функцию.
От: Аноним  
Дата: 16.01.09 07:35
Оценка:
Здравствуйте, Аноним, Вы писали:

А>эмм безопасен ли вот такой код?


А>
А>int i;
А>double const& foo(double const& rd){
А>  return rd;
А>}

А>double d = foo(static_cast<double>(i));
А>


А>правильно ли я понимаю, что фунция foo получает ссылку на временный объект типа double, и в дальнейшем ее же вовзвращает, поэтому дальнейшие операции с ней не корректны?


проверить можно так


struct Test
{
    Test()
    {
        cout<<"ctor"<<endl;
    }
    ~Test()
    {
        cout<<"dtor"<<endl;
    }

};
Test const &foo(Test const &rd)
{
    return rd;
}

int main(int argc, char* argv[])
{
    //оставте один вариант и посмотрите когда вызывается деструктор
    Test const & correct = Test();
    Test const & wrong = foo(Test());
Re[8]: возврат ссылки на переданные по ссылке данные в функц
От: Vain Россия google.ru
Дата: 16.01.09 09:26
Оценка:
Здравствуйте, rg45, Вы писали:

AG>>не компилируется, добавляем const, получаем, как и ожидалось "r is NOT valid" уже после "dtor\n".

R>Так, я запутался... Как тогда понимать 12.2/5
Так и понимать: "end of the full-expression" есть точка с запятой, а не скобка.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[6]: возврат ссылки на переданные по ссылке данные в функц
От: rg45 СССР  
Дата: 16.01.09 11:30
Оценка:
Здравствуйте, Vamp, Вы писали:

V>Это не важно. У нас тут получается длинная цепочка ссылок на временные объект, который будет жить до тех пор, пока живет хотя бы одна из них.


Все-таки, склоняюсь к мысли, что это неверное утверждение. Формулировка в стандарте выглядит недостаточно четкой. Но рассуждения приведенные здесь
Автор:
Дата: 16.01.09
, выглядят достаточно здраво. В самом деле, для того, чтобы продлить время жизни объекта, переданного в функцию по ссылке, компилятор должен откуда-то узнать, что ссылка-параметр и ссылка-результат ссылаются на один и тот же временный объект. Компилятор это может узнать в компайл-тайме, если в точке вызова функции будет видеть ее определение, на что в общем случае расчитывать не приходится. Другой вариант — компилятор может сгенерировать код, который в ран-тайме будет определять идентичность ссылок. Такое требование к кодогенерации тоже вряд ли можно назвать разумным.
--
Справедливость выше закона. А человечность выше справедливости.
Re[4]: возврат ссылки на переданные по ссылке данные в функц
От: Аноним  
Дата: 16.01.09 13:44
Оценка:
AG>>Почему валидна?
V>Потому, что время жизни временного объекта, к которому привязана ссылка, продлевается до тех пор, пока жива ссылка на него.
Нет. В С++ вполне можно получить невалидную ссылку и все такие же прелести которые присущи невалидному указателю.
Что касается примера выше — там UB. Временные объекты разрушаются при выходе из выражения, при вычиселнии которого они используются, т.е. задолго до выхода из функции где это выражение написано. Но код падать скорее всего не будет, и при определенной степени везучести даже QA могут ничего не найти)
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.