const& foo VS const foo
От: valexey_  
Дата: 19.03.13 14:39
Оценка:
Вопрос — отличается ли семантика ссылки на константу от самой константы в следующем случае:

Foo foo();
...
const Foo& a = foo();
const Foo  b = foo();


Соответственно тип Foo — произвольный.
c++
Re: const& foo VS const foo
От: saf_e  
Дата: 19.03.13 15:34
Оценка: -7
Здравствуйте, valexey_, Вы писали:

_>Вопрос — отличается ли семантика ссылки на константу от самой константы в следующем случае:


_>
_>Foo foo();
_>...
_>const Foo& a = foo();
_>const Foo  b = foo();
_>


_>Соответственно тип Foo — произвольный.


Foo foo();
...
const Foo& a = foo(); // здесь будет ссылка на временный объект, который будет разрушен и следовательно ссылка будет невалидна
const Foo  b = foo(); // здесь получите полноценную копию
Re[2]: const& foo VS const foo
От: Evgeny.Panasyuk Россия  
Дата: 19.03.13 15:41
Оценка: 1 (1)
Здравствуйте, saf_e, Вы писали:

_>const Foo& a = foo(); // здесь будет ссылка на временный объект, который будет разрушен и следовательно ссылка будет невалидна


http://www.lmgtfy.com/?q=C%2B%2B+const+reference+prolongs+life+of&l=1
Re[2]: const& foo VS const foo
От: valexey_  
Дата: 19.03.13 15:44
Оценка:
Здравствуйте, saf_e, Вы писали:

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


_>>Вопрос — отличается ли семантика ссылки на константу от самой константы в следующем случае:


_>>
_>>Foo foo();
_>>...
_>>const Foo& a = foo();
_>>const Foo  b = foo();
_>>


_>>Соответственно тип Foo — произвольный.


_>
_>Foo foo();
_>...
_>const Foo& a = foo(); // здесь будет ссылка на временный объект, который будет разрушен и следовательно ссылка будет невалидна
_>const Foo  b = foo(); // здесь получите полноценную копию
_>


IMHO ты путаешь с указателем на временный объект. Например согласно 14.1/6 стандарта (точнее драфта стандарта от 2005 года: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1905.pdf страница 277) имеем такое:
const int & cri = i ; // OK: const reference bound to temporary


const reference на возвращаемое значение — абсолютно валидная операция (подробней см. 12.2)

Ссылка (ака reference) не сводится к константному указателю в С++.
Re[3]: const& foo VS const foo
От: saf_e  
Дата: 19.03.13 15:46
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

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


_>>const Foo& a = foo(); // здесь будет ссылка на временный объект, который будет разрушен и следовательно ссылка будет невалидна


EP>http://www.lmgtfy.com/?q=C%2B%2B+const+reference+prolongs+life+of&l=1


Спасибо почитал
Re: const& foo VS const foo
От: uzhas Ниоткуда  
Дата: 19.03.13 15:49
Оценка:
Здравствуйте, valexey_, Вы писали:

_>const Foo& a = foo();

_>const Foo b = foo();

лично я приучил себя использовать первый вариант в надежде, что компилятор соптимизирует что-то там и разместить объект где-нибудь в легко доступном месте (хотя куда уж шустрее стека?)
но на практике так и не ощутил выигрыша
видимо, не умею готовить
Re[2]: const& foo VS const foo
От: valexey_  
Дата: 19.03.13 15:51
Оценка:
Здравствуйте, uzhas, Вы писали:

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


_>>const Foo& a = foo();

_>>const Foo b = foo();

U>лично я приучил себя использовать первый вариант в надежде, что компилятор соптимизирует что-то там и разместить объект где-нибудь в легко доступном месте (хотя куда уж шустрее стека?)

U>но на практике так и не ощутил выигрыша
U>видимо, не умею готовить

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

Быть может есть различие в последующей жизни a и b? Может есть что-то такое что можно с 'a' сделать но нельзя с 'b' и наоборот?
Re[2]: const& foo VS const foo
От: saf_e  
Дата: 19.03.13 15:51
Оценка:
Здравствуйте, uzhas, Вы писали:

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


_>>const Foo& a = foo();

_>>const Foo b = foo();

U>лично я приучил себя использовать первый вариант в надежде, что компилятор соптимизирует что-то там и разместить объект где-нибудь в легко доступном месте (хотя куда уж шустрее стека?)

U>но на практике так и не ощутил выигрыша
U>видимо, не умею готовить

Как-то это прошло мимо меня Всю жизнь избегал такого, опасаясь что объект будет разрушен и надеялся на return-value optimization
Re[3]: const& foo VS const foo
От: saf_e  
Дата: 19.03.13 15:53
Оценка:
Здравствуйте, valexey_, Вы писали:

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


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


_>>>const Foo& a = foo();

_>>>const Foo b = foo();

U>>лично я приучил себя использовать первый вариант в надежде, что компилятор соптимизирует что-то там и разместить объект где-нибудь в легко доступном месте (хотя куда уж шустрее стека?)

U>>но на практике так и не ощутил выигрыша
U>>видимо, не умею готовить

_>Ну, можно в регистр запихать Но штука в том, что в обоих случаях на современных компиляторах лишней копии объекта не наблюдается. Да и оптимизации применяются вроде бы одни и те же.


_>Быть может есть различие в последующей жизни a и b? Может есть что-то такое что можно с 'a' сделать но нельзя с 'b' и наоборот?


Тогда получается, что если компилятор не умеет делать return-value optimization, то первый вариант эффективнее. Больше никакой разницы не наблюдаю...
Re[4]: const& foo VS const foo
От: valexey_  
Дата: 19.03.13 16:27
Оценка:
Здравствуйте, saf_e, Вы писали:

_>Тогда получается, что если компилятор не умеет делать return-value optimization, то первый вариант эффективнее. Больше никакой разницы не наблюдаю...


Не думаю что все так просто. Быть может семантика const_cast'а над этими значениями будет отличаться например.
Re[5]: const& foo VS const foo
От: saf_e  
Дата: 19.03.13 16:35
Оценка:
Здравствуйте, valexey_, Вы писали:

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


_>>Тогда получается, что если компилятор не умеет делать return-value optimization, то первый вариант эффективнее. Больше никакой разницы не наблюдаю...


_>Не думаю что все так просто. Быть может семантика const_cast'а над этими значениями будет отличаться например.


Не думаю что тут есть какие-то сложности. Семантически ссылка на объект и сам объект отличаются только временем жизни. А в данном примере не отличаются и этим
Re[6]: const& foo VS const foo
От: valexey_  
Дата: 19.03.13 16:40
Оценка: -1
Здравствуйте, saf_e, Вы писали:

_>>Не думаю что все так просто. Быть может семантика const_cast'а над этими значениями будет отличаться например.


_>Не думаю что тут есть какие-то сложности. Семантически ссылка на объект и сам объект отличаются только временем жизни. А в данном примере не отличаются и этим


Ну вот чуть другой пример, где поведение отличается на некоторых компиляторах:

#include <iostream>
using namespace std;

void foo(int* p) {*p=12;}

int main() {
    const int& a = 42;
    const int  b = 42;
    foo(const_cast<int*>(&a));
    foo(const_cast<int*>(&b));
    cout << a << " " << b  << endl;
    return 0;
}
Re[7]: const& foo VS const foo
От: saf_e  
Дата: 19.03.13 16:44
Оценка: +1
Здравствуйте, valexey_, Вы писали:

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


_>>>Не думаю что все так просто. Быть может семантика const_cast'а над этими значениями будет отличаться например.


_>>Не думаю что тут есть какие-то сложности. Семантически ссылка на объект и сам объект отличаются только временем жизни. А в данном примере не отличаются и этим


_>Ну вот чуть другой пример, где поведение отличается на некоторых компиляторах:


_>
_>#include <iostream>
_>using namespace std;

_>void foo(int* p) {*p=12;}

_>int main() {
_>    const int& a = 42;
_>    const int  b = 42;
_>    foo(const_cast<int*>(&a));
_>    foo(const_cast<int*>(&b));
_>    cout << a << " " << b  << endl;
_>    return 0;
_>}
_>


Выполнение этого кода undefined behaviuor в чистом виде.
Re[8]: const& foo VS const foo
От: valexey_  
Дата: 19.03.13 16:47
Оценка:
Здравствуйте, saf_e, Вы писали:

_>>Ну вот чуть другой пример, где поведение отличается на некоторых компиляторах:


_>>
_>>#include <iostream>
_>>using namespace std;

_>>void foo(int* p) {*p=12;}

_>>int main() {
_>>    const int& a = 42;
_>>    const int  b = 42;
_>>    foo(const_cast<int*>(&a));
_>>    foo(const_cast<int*>(&b));
_>>    cout << a << " " << b  << endl;
_>>    return 0;
_>>}
_>>


_>Выполнение этого кода undefined behaviuor в чистом виде.


Для обоих случаев? И если да, то согласно чему это будет UB?
Re[9]: const& foo VS const foo
От: saf_e  
Дата: 19.03.13 16:54
Оценка:
Здравствуйте, valexey_, Вы писали:

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


_>>>Ну вот чуть другой пример, где поведение отличается на некоторых компиляторах:


_>>>
_>>>#include <iostream>
_>>>using namespace std;

_>>>void foo(int* p) {*p=12;}

_>>>int main() {
_>>>    const int& a = 42;
_>>>    const int  b = 42;
_>>>    foo(const_cast<int*>(&a));
_>>>    foo(const_cast<int*>(&b));
_>>>    cout << a << " " << b  << endl;
_>>>    return 0;
_>>>}
_>>>


_>>Выполнение этого кода undefined behaviuor в чистом виде.


_>Для обоих случаев? И если да, то согласно чему это будет UB?


У вас нет гарантии что память в которой размещены константы будет доступна на запись, это раз.
И второе, компилятор с чистой совестью может полагать что значение констант, в данном коде, не будет изменено.
Re[10]: const& foo VS const foo
От: valexey_  
Дата: 19.03.13 17:05
Оценка:
Здравствуйте, saf_e, Вы писали:

_>>>>
_>>>>#include <iostream>
_>>>>using namespace std;

_>>>>void foo(int* p) {*p=12;}

_>>>>int main() {
_>>>>    const int& a = 42;
_>>>>    const int  b = 42;
_>>>>    foo(const_cast<int*>(&a));
_>>>>    foo(const_cast<int*>(&b));
_>>>>    cout << a << " " << b  << endl;
_>>>>    return 0;
_>>>>}
_>>>>


_>>>Выполнение этого кода undefined behaviuor в чистом виде.


_>>Для обоих случаев? И если да, то согласно чему это будет UB?


_>У вас нет гарантии что память в которой размещены константы будет доступна на запись, это раз.

_>И второе, компилятор с чистой совестью может полагать что значение констант, в данном коде, не будет изменено.

В случае const int& -- IMHO, есть. По аналогии с тем же 14.1/6, будет гарантировано const reference bound to temporary. Что в общем то и наблюдаем в случае gcc: 'a' в результате манипуляций меняется на 12, а вот 'b' нет.

Для пущей ясности, уберем литерал и заменим его на "переменную":

#include <iostream>
using namespace std;

void foo(int* p) {*p=12;}

int main() {
    const int z = 42;
    const int& a = z;
    const int  b = z;
    foo(const_cast<int*>(&a));
    foo(const_cast<int*>(&b));
    cout << a << " " << b << " " << z  << endl;
    return 0;
}


Результат:
12 42 42

Таким образом z и b не изменились, а вот содержимое 'a' изменилось.

Результат одинаков на clang и gcc. Пробовал и с -O0 и c -O3
Re[11]: const& foo VS const foo
От: valexey_  
Дата: 19.03.13 17:09
Оценка:
_>Результат одинаков на clang и gcc. Пробовал и с -O0 и c -O3

Впрочем, я не утверждаю что тут нет UB. Просто хочется разобраться. И очевидно отличия в семантике какие-то все же есть, коль вылезает разное поведение (пусть даже из за UB) на некоторых компиляторах.
Re[12]: const& foo VS const foo
От: saf_e  
Дата: 19.03.13 17:15
Оценка:
Здравствуйте, valexey_, Вы писали:

_>>Результат одинаков на clang и gcc. Пробовал и с -O0 и c -O3


_>Впрочем, я не утверждаю что тут нет UB. Просто хочется разобраться. И очевидно отличия в семантике какие-то все же есть, коль вылезает разное поведение (пусть даже из за UB) на некоторых компиляторах.


Тут скорее вопрос как конкретный компилятор трактует код.

Могу сказать одно, практического смысла тут 0, такого кода стоит избегать. ИМХО, в любых практических аспектах разницы быть не должно.
Re[11]: const& foo VS const foo
От: watch-maker  
Дата: 19.03.13 17:19
Оценка:
Здравствуйте, valexey_, Вы писали:

_>>>согласно чему это будет UB?

7.1.5.1 4
Except that any class member declared mutable (7.1.1) can be modified, any attempt to modify a const object during its lifetime (3.8) results in undefined behavior.

Дальше в стандарте идёт пример, где показано когда запись по указателю, полученному через const_cast, делать можно, а когда нельзя. Похожий на твой код там есть, и отнюдь не в разделе «можно».

_>>У вас нет гарантии что память в которой размещены константы будет доступна на запись, это раз.

Это ещё не самое страшное. Ужасы начинаются когда когда значение константы таки удаётся изменить. И тогда где-то в другом месте программы вмести «42» будет подставляться «12».

_>В случае const int& -- IMHO, есть. По аналогии с тем же 14.1/6, будет гарантировано const reference bound to temporary. Что в общем то и наблюдаем в случае gcc: 'a' в результате манипуляций меняется на 12, а вот 'b' нет.


_>Для пущей ясности, уберем литерал и заменим его на "переменную":

_>Результат одинаков на clang и gcc. Пробовал и с -O0 и c -O3

Это всё UB, причём довольно неинтересное.
Re[12]: const& foo VS const foo
От: saf_e  
Дата: 19.03.13 17:21
Оценка:
Здравствуйте, watch-maker, Вы писали:

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


_>>>>согласно чему это будет UB?

WM>

7.1.5.1 4
WM>Except that any class member declared mutable (7.1.1) can be modified, any attempt to modify a const object during its lifetime (3.8) results in undefined behavior.

WM>Дальше в стандарте идёт пример, где показано когда запись по указателю, полученному через const_cast, делать можно, а когда нельзя. Похожий на твой код там есть, и отнюдь не в разделе «можно».

_>>>У вас нет гарантии что память в которой размещены константы будет доступна на запись, это раз.

WM>Это ещё не самое страшное. Ужасы начинаются когда когда значение константы таки удаётся изменить. И тогда где-то в другом месте программы вмести «42» будет подставляться «12».

_>>В случае const int& -- IMHO, есть. По аналогии с тем же 14.1/6, будет гарантировано const reference bound to temporary. Что в общем то и наблюдаем в случае gcc: 'a' в результате манипуляций меняется на 12, а вот 'b' нет.


_>>Для пущей ясности, уберем литерал и заменим его на "переменную":

_>>Результат одинаков на clang и gcc. Пробовал и с -O0 и c -O3

WM>Это всё UB, причём довольно неинтересное.


Когда UB интересное его начинают активно использовать и это еще хуже
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.