Форум программистов, компьютерный форум CyberForum.ru

Ссылка на временный объект - C++

Восстановить пароль Регистрация
 
 
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
11.08.2014, 03:24     Ссылка на временный объект #1
Наткнулся тут в гугле на одну интересную тему.
Как известно, данный код не соответствует стандарту, и не будет скомпилирован многими современными компиляторами:

C++
1
2
3
4
5
6
7
8
9
10
11
class A {
 
};
 
void f( A & ) {
   
}
 
int main() {
   f( A());
}
Но данный код компилируется, и вполне валиден:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class A {
public:
   A &getThis() {
      return *this;
   }
};
 
void f( A & ) {
   
}
 
int main() {
   f( A().getThis());
}
Собственно, вопрос: почему он валиден?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
CyberSolver
 Аватар для CyberSolver
101 / 74 / 17
Регистрация: 23.07.2014
Сообщений: 686
Записей в блоге: 1
11.08.2014, 07:27     Ссылка на временный объект #2
Toshkarik, в первом случае ссылка на временный объект, вы сами себе и ответили. Во-втором — функция возвращает ссылку на A, у функции такие же параметры. Почему это не должно скомпилироваться?
DrOffset
6424 / 3798 / 879
Регистрация: 30.01.2014
Сообщений: 6,591
11.08.2014, 08:56     Ссылка на временный объект #3
Цитата Сообщение от Toshkarik Посмотреть сообщение
Собственно, вопрос: почему он валиден?
Выражение A(); является rvalue. Причем неконстантным rvalue.
Метод getThis() возвращает lvalue.
Потому и валиден.
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
11.08.2014, 12:51  [ТС]     Ссылка на временный объект #4
Почему компилируется понянто. Вопрос в другом, почему в этом случая временный объект живет до выхода из функции. Интересует не техническая часть, а почему это допустили. По сути мы схитрили и все же использовали временный объект для передали по ссылке в качестве параметра.
0x10
2425 / 1597 / 232
Регистрация: 24.11.2012
Сообщений: 3,919
11.08.2014, 12:58     Ссылка на временный объект #5
Toshkarik, временные объекты пока выполняется выражение.
Мб кто-нибудь приведет прямо ссылку на стандарт.
soon
 Аватар для soon
2536 / 1301 / 81
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
11.08.2014, 13:04     Ссылка на временный объект #6
N3337 12.2/3

When an implementation introduces a temporary object of a class that has a non-trivial constructor (12.1, 12.8), it shall ensure that a constructor is called for the temporary object. Similarly, the destructor shall be called for a temporary with a non-trivial destructor (12.4). Temporary objects are destroyed as the last step in evaluating the full-expression (1.9) that (lexically) contains the point where they were created. This is true even if that evaluation ends in throwing an exception. The value computations and side effects of destroying a temporary object are associated only with the full-expression, not with any specific subexpression.
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
11.08.2014, 13:07  [ТС]     Ссылка на временный объект #7
И про это в курсе, имеется в виду full-expression, ссылку на стандарт сейчас не дам, так как не помню. Может опять неправильно выразился. Попробуем наоборот: если возможен второй вариант, то почему запретили первый? Это же выглядит немного как "хак". Может быть, это одна из причин появления rvalue-reference в C++11...

Не по теме:

upd: А вот и стандарт

ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
11.08.2014, 13:19     Ссылка на временный объект #8
Toshkarik, Как-то спрашивал про то, почему разрешена конверсия от rvalue к lvalue на SO, впринципе там ответили довольно полно: http://stackoverflow.com/questions/1...-visual-studio
DrOffset
6424 / 3798 / 879
Регистрация: 30.01.2014
Сообщений: 6,591
11.08.2014, 13:39     Ссылка на временный объект #9
Цитата Сообщение от Toshkarik Посмотреть сообщение
почему запретили первый?
Это попытка запретить опасное использование. Если я не ошибаюсь, то предложение запрета первого варианта исходил от самого Страуструпа. А второй вариант запретить нельзя. Потому что, например, его не отличить вот от такого (пример утрирован):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class A {
public:
   A(A * ref) : ref_(ref) {}
   A() : ref_(this) {}
   A &getThis() {
      return *ref_;
   }
   A * ref_;
};
 
void f( A & ) {
   
}
 
int main() {
   A a;
   f( A(&a).getThis());
}
Tulosba
:)
Эксперт C++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
11.08.2014, 14:02     Ссылка на временный объект #10
Цитата Сообщение от Toshkarik Посмотреть сообщение
По сути мы схитрили
Именно в этом всё дело. Стандарт дает (старается дать) защиту от явных ошибок. Но когда программист хочет обойти защиту, он ее обойдет.
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
11.08.2014, 14:23  [ТС]     Ссылка на временный объект #11
Так ведь непонятно в данном случае - от чего защищают?
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
11.08.2014, 14:27     Ссылка на временный объект #12
Toshkarik, Не знаю насколько я буду прав, но первый вариант не должен работать для POD типов, для них ведь никак не сэмулировать второй вариант. В то время как для классов вцелом может.

C++
1
2
3
4
5
6
7
8
void function(int& v)
{
}
 
int main()
{
   function(1);
}
Мы пытаемся привязать константу к lvalue-reference, что абсолютно неверно.
Tulosba
:)
Эксперт C++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
11.08.2014, 14:29     Ссылка на временный объект #13
Цитата Сообщение от Toshkarik Посмотреть сообщение
Так ведь непонятно в данном случае - от чего защищают?
От бесполезной модификации временного объекта.
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
11.08.2014, 14:46  [ТС]     Ссылка на временный объект #14
ForEveR, сейчас вопрос уже не в эмуляции, а в самом запрете. Ведь вполне можно было создать временный объект, даже POD, и передать его в функцию по ссылке, если гарантируется его время жизни ( временного объекта ).

Цитата Сообщение от Tulosba Посмотреть сообщение
От бесполезной модификации временного объекта.
Ну почему сразу бесполезной, вполне можно найти полезное применение. Ведь это одна из целей, как я понимаю, rvalue reference. Возможно, ошибаюсь.
Tulosba
:)
Эксперт C++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
11.08.2014, 14:48     Ссылка на временный объект #15
Цитата Сообщение от Toshkarik Посмотреть сообщение
Ну почему сразу бесполезной, вполне можно найти полезное применение.
Как оно может быть полезным, если объект будет уничтожен после всех манипуляций?
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
11.08.2014, 15:02  [ТС]     Ссылка на временный объект #16
Я уже не найду, наверно, статью, в которой показывались новшества C++11 и способы достижения некоторых из них в C++03( 98 ). Я ведь не настаиваю ни на чем. Просто хотелось бы понять "создателей" языка/стандартов. Если бы небыло хоть в чем то полезным, то я не нашел бы этого способа в интернете. Конечно, я понимаю, что экспериментаторов тоже хватает.
0x10
2425 / 1597 / 232
Регистрация: 24.11.2012
Сообщений: 3,919
11.08.2014, 15:38     Ссылка на временный объект #17
Цитата Сообщение от Toshkarik Посмотреть сообщение
Просто хотелось бы понять "создателей" языка/стандартов.
Они не боги, а такие же люди. Не каждая возможность языка имеет глубокий смысл и кейс к применению, где иначе было бы нельзя.
"If you think C++ is not overly complicated, just what is a “protected abstract virtual base pure virtual private destructor,” and when was the last time you needed one?", - Tom Cargill (1990).
Цитата взята с седьмого слайда доклада: https://tech.yandex.ru/events/cpp-pa...sk/talks/1954/
DrOffset
6424 / 3798 / 879
Регистрация: 30.01.2014
Сообщений: 6,591
11.08.2014, 18:11     Ссылка на временный объект #18
Цитата Сообщение от Toshkarik Посмотреть сообщение
Просто хотелось бы понять "создателей" языка/стандартов.
Защита в том числе от висячих ссылок. Уж больно просто их создать становится.
C++
1
2
С & c = C();
c.foo(); // fail
А так конечно любую защиту можно сломать, и если ты сейчас приведешь пяток способов создать висячую ссылку, то это не будет значить, что я не прав. А будет значить только лишь то, что нет в мире совершенных инструментов (наш мозг в том числе).
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11815 / 6794 / 769
Регистрация: 27.09.2012
Сообщений: 16,867
Записей в блоге: 2
Завершенные тесты: 1
11.08.2014, 21:08     Ссылка на временный объект #19
C++
1
2
С & c = C();
c.foo(); // fail
DrOffset, а как же:
There are two contexts in which temporaries are destroyed at a different point than the end of the full-expression. The first context is when a default constructor is called to initialize an element of an array. If the constructor has one or more default arguments, the destruction of every temporary created in a default argument is sequenced before the construction of the next array element, if any.


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 of a subobject to which the reference is bound persists for the lifetime of the reference except:
— 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.
— The lifetime of a temporary bound to the returned value in a function return statement (6.6.3) is not extended; the temporary is destroyed at the end of the full-expression in the return statement.
— 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.

The destruction of a temporary whose lifetime is not extended by being bound to a reference is sequenced before the destruction of every temporary which is constructed earlier in the same full-expression. 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, thread, or automatic storage duration
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.08.2014, 21:41     Ссылка на временный объект
Еще ссылки по теме:

Ссылка на объект, возвращаемый функцией C++
Может ли объект-член, или объект-элемент достучаться к содержащему его? C++
C++ Ссылка на объект класса

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
DrOffset
6424 / 3798 / 879
Регистрация: 30.01.2014
Сообщений: 6,591
11.08.2014, 21:41     Ссылка на временный объект #20
Цитата Сообщение от Croessmah Посмотреть сообщение
а как же:
Все это хорошо, только не понятно к чему ты это написал. Никаких откровений я тут не увидел.
Я честно пытался угадать что ты имел в виду, но что-то не выходит. Поясни.

Добавлено через 8 минут
Хотя я кажется догадался. Если каким-либо образом нарушить вышеописанные правила, то получим висячие ссылки. Ну так на это у меня как раз была заготовлена фраза:
Цитата Сообщение от DrOffset Посмотреть сообщение
если ты сейчас приведешь пяток способов создать висячую ссылку, то это не будет значить, что я не прав. А будет значить только лишь то, что нет в мире совершенных инструментов (наш мозг в том числе).
С++ не из тех языков, которые будут поддерживать штаны разработчика. Следовательно ожидать от него чрезмерной заботы не стоит. Достаточно уже того, что все эти моменты описаны в стандарте. Если подумать, то легко можно объяснить, почему такие вещи не запрещены синтаксисом. Я думаю, ты и сам это знаешь.
Yandex
Объявления
11.08.2014, 21:41     Ссылка на временный объект
Ответ Создать тему
Опции темы

Текущее время: 20:27. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru