Автор Тема: C++ инициализация ссылок  (Прочитано 57271 раз)

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: C++ инициализация ссылок
« Ответ #45 : Март 19, 2013, 02:17:36 pm »
Проверил с выносом foo в динамическую либу (g++) - все так же.
Y = λf.(λx.f (x x)) (λx.f (x x))

DddIzer

  • Гость
Re: C++ инициализация ссылок
« Ответ #46 : Март 19, 2013, 02:22:34 pm »
Не оО, а o0.
 8)
так вот в чем фишка... "истина" нуле, а я то думал.. впрочем воистину С++ язык для не очень простых  людей, я бы сказал совсем мне простых... это надо же так
х..ню напишешь, запустишь, просишь эмулировать...  а потом пару дней думаешь... а что бы это значило.

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: C++ инициализация ссылок
« Ответ #47 : Март 19, 2013, 02:36:03 pm »
Не оО, а o0.
 8)
так вот в чем фишка... "истина" нуле, а я то думал.. впрочем воистину С++ язык для не очень простых  людей, я бы сказал совсем мне простых... это надо же так
х..ню напишешь, запустишь, просишь эмулировать...  а потом пару дней думаешь... а что бы это значило.
Да нет, с тем что там просил эмулировать благополучно разобрались же - ссылка не эквивалентна указателю и через указатель не эмулируется в общем случае.

Осталось разобраться, в одном конкретном случае, эквивалентна ли ссылка на константу самой константе. Хотя, если подумать... Ссылка это алиас, алиас на константу остается той же самой константой. В чем вопрос, спрашивается? :-)
Y = λf.(λx.f (x x)) (λx.f (x x))

DddIzer

  • Гость
Re: C++ инициализация ссылок
« Ответ #48 : Март 19, 2013, 02:38:57 pm »
В чем вопрос, спрашивается? :-)
  На фига козе боян? - кажется так.. :D

Berserker

  • Sr. Member
  • ****
  • Сообщений: 254
    • Просмотр профиля
Re: C++ инициализация ссылок
« Ответ #49 : Март 19, 2013, 06:07:50 pm »
const O o1  = foo();
nt i;
cin >> i;

1 раз создаётся объект, затем ожидание ввода, затем он удаляется. GCC не генерирует лишнее копирование.

const O &o1  = foo();
nt i;
cin >> i;

Результат идентичен. Что и требовалось доказать.

В чистом примере от Алексея деструктор вызывался из-за того, что элементы в локальных блоках помещены.

P.S. Отключил оптимизацию, но результат не изменился.

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: C++ инициализация ссылок
« Ответ #50 : Март 20, 2013, 03:29:25 pm »
const O o1  = foo();
nt i;
cin >> i;

1 раз создаётся объект, затем ожидание ввода, затем он удаляется. GCC не генерирует лишнее копирование.

const O &o1  = foo();
nt i;
cin >> i;

Результат идентичен. Что и требовалось доказать.

В чистом примере от Алексея деструктор вызывался из-за того, что элементы в локальных блоках помещены.

P.S. Отключил оптимизацию, но результат не изменился.

Эмм... Ты всего лишь показал то, о чем я говорил - в том примере действительно идентичны поведения были и требовалось поставить такой эксперимент, который выявил бы различия. В блоки я переменные засунул для того, чтобы сгруппировать конструктор-деструктор для каждой из переменной (и там тоже было симметрично). То есть чтобы было не: O(), O(), ~O(), ~O(), а O(),~O(),O(),~O()
Y = λf.(λx.f (x x)) (λx.f (x x))

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: C++ инициализация ссылок
« Ответ #51 : Март 20, 2013, 03:49:25 pm »
Итак, отличия таки нашлись.
Ну, во-первых:
если у нас foo() внезапно начнет возвращать не переменную типа O, а таки O& (решили соптимизировать - возвращаем некую долгоживующую переменную, нет смысла создавать локальную копию её), то все внезапно поменяется:
#include <iostream>
using namespace std;
struct O {
int foo;
        O(int i) : foo(i) {cout << "O(" << i <<")\n";}
O(const O& r) {foo=r.foo; cout << "Copy constructor\n";}
~O(){cout << "~O(" << foo << ")\n";}
O& operator=(const O& r) {cout << "=\n"; return *this;}
};

O o(0);
O& foo() {
    return o;
}

int main() {
    cout << "=== begin ===\n";
    {const O& o0 = foo();}
    cout << "--- mmMmm ---\n";
    {const O  o1 = foo();}
    cout << "===  end  ===\n";
    return 0;
}

Программа напишет теперь такое:
O(0)
=== begin ===
--- mmMmm ---
Copy constructor
~O(0)
===  end  ===
~O(0)
То есть в случае const O o1 = foo(); будет создавать копию переменной (вызывая для этого копирующий конструктор), а const O& = foo(); как было оптимальным так и останется. Никто ничего не заметит.
http://liveworkspace.org/code/1vbybT$1

Это первое семантическое отличие. А вот второе:
struct Foo
{
   Foo(Foo &&)=delete;
   Foo(int,int) {}
};

Foo create() { return {12,42}; }

int main()
{
   const Foo &t1 = create(); // OK
   const Foo t2  = create(); // error
}
Во втором случае (t2) требуется от типа Foo наличие move semantic (семантики перемещения). http://liveworkspace.org/code/3ylY4h$21

Все это отрылось по результатам обсуждения на rsdn: http://rsdn.ru/forum/cpp/5104989.flat.1
Y = λf.(λx.f (x x)) (λx.f (x x))

DddIzer

  • Гость
Re: C++ инициализация ссылок
« Ответ #52 : Март 20, 2013, 03:58:42 pm »
Итак, отличия таки нашлись.
Ну, во-первых:
если у нас foo() внезапно начнет возвращать не переменную типа O, а таки O& (решили соптимизировать - возвращаем некую долгоживующую переменную, нет смысла создавать локальную копию её), то все внезапно поменяется:

:D ГЫ...  ЭТОТ вариант как раз и не интересовал меня...( поскольку он имеет смысл) в отличие от фигни предложенной вами в начале...

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: C++ инициализация ссылок
« Ответ #53 : Март 20, 2013, 03:59:18 pm »
Итак, отличия таки нашлись.
Ну, во-первых:
если у нас foo() внезапно начнет возвращать не переменную типа O, а таки O& (решили соптимизировать - возвращаем некую долгоживующую переменную, нет смысла создавать локальную копию её), то все внезапно поменяется:

:D ГЫ...  ЭТОТ вариант как раз и не интересовал меня...( поскольку он имеет смысл) в отличие от фигни предложенной вами в начале...
Какой именно?
Y = λf.(λx.f (x x)) (λx.f (x x))

DddIzer

  • Гость
Re: C++ инициализация ссылок
« Ответ #54 : Март 20, 2013, 04:03:31 pm »
Итак, отличия таки нашлись.
Ну, во-первых:
если у нас foo() внезапно начнет возвращать не переменную типа O, а таки O& (решили соптимизировать - возвращаем некую долгоживующую переменную, нет смысла создавать локальную копию её), то все внезапно поменяется:

:D ГЫ...  ЭТОТ вариант как раз и не интересовал меня...( поскольку он имеет смысл) в отличие от фигни предложенной вами в начале...
Какой именно?
Самый первый - обычное ЗНАЧЕНИЕ возвращаемое функцией (содержащееся в локальной переменной ).

DddIzer

  • Гость
Re: C++ инициализация ссылок
« Ответ #55 : Март 20, 2013, 04:06:10 pm »
(решили соптимизировать - возвращаем некую долгоживующую переменную, нет смысла создавать локальную копию её), то все внезапно поменяется:


Вопрос - в каком месте прописана  заведомая "оптимальность" выбора?

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: C++ инициализация ссылок
« Ответ #56 : Март 20, 2013, 04:16:32 pm »
(решили соптимизировать - возвращаем некую долгоживующую переменную, нет смысла создавать локальную копию её), то все внезапно поменяется:


Вопрос - в каком месте прописана  заведомая "оптимальность" выбора?
Оптимальность определяется в контексте конкретного кода, задачи, ресурсов и ТЗ.
Y = λf.(λx.f (x x)) (λx.f (x x))

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: C++ инициализация ссылок
« Ответ #57 : Март 20, 2013, 04:20:36 pm »
:D ГЫ...  ЭТОТ вариант как раз и не интересовал меня...( поскольку он имеет смысл) в отличие от фигни предложенной вами в начале...
Какой именно?
Самый первый - обычное ЗНАЧЕНИЕ возвращаемое функцией (содержащееся в локальной переменной ).
Это была всего лишь иллюстрация того, что семантика ссылки в С++ отличается от семантики любых указателей. То есть ссылка в С++ не является лишь синтаксическим сахаром над указателем.

Далее возникла задача (точнее мне просто стало интересно) показать отличие const Foo foo от const Foo& foo не в качестве аргументов функций. Что вполне удалось.
Y = λf.(λx.f (x x)) (λx.f (x x))

DddIzer

  • Гость
Re: C++ инициализация ссылок
« Ответ #58 : Март 20, 2013, 04:22:49 pm »

Оптимальность определяется в контексте конкретного кода, задачи, ресурсов и ТЗ.
ммм... не то.... ре формулирую вопрос... с чего где прописана ОБЯЗАННОСТЬ компилятора оптимизировать этот момент?

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: C++ инициализация ссылок
« Ответ #59 : Март 20, 2013, 04:30:31 pm »

Оптимальность определяется в контексте конкретного кода, задачи, ресурсов и ТЗ.
ммм... не то.... ре формулирую вопрос... с чего где прописана ОБЯЗАННОСТЬ компилятора оптимизировать этот момент?
Дык, это не оптимизация. Тут имеем тупо алиас на алиас, алиасы, вообще говоря, не должны создавать новых переменных/объектов (в том числе не должны вызывать какие-либо конструкторы). Ну вот оно и не создает.

В случае const Foo bar; имеем не алиас а самостоятельную константу, то есть этот самый bar не должен измениться когда изменится оригинальное значение. Константность у ссылки и у переменной имеет разный смысл.
Y = λf.(λx.f (x x)) (λx.f (x x))