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

DddIzer

  • Гость
Re: C++ инициализация ссылок
« Ответ #105 : Март 25, 2013, 02:55:33 pm »
Потому что без более-менее точного представления о физической реализации невозможно писать хороший код с точки зрения эффективности. А в С++ в ряде мест используется магия слов и понятий, затуманивающих явления. Те же ссылки невозможно реализовать без указателей в общем случае. Более того, у них все свойства указателей де-факто сохраняются. При этом FAQ пишет такие вещи как «Reference IS Object», что просто улыбка с лица не сходит.
Если нужна эффективная реализация (с точки зрения максимальной отдачи от железа)- используйте ассемблер... меня раздражает другое какого хрена тыкают в реализацию даже в том случае , когда исходная задача не формулируется в низкоуровневых моделях.. лично я вижу одно обьяснение этому  - тяжелое наследие прошлого...

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: C++ инициализация ссылок
« Ответ #106 : Март 25, 2013, 03:23:07 pm »
Потому что без более-менее точного представления о физической реализации невозможно писать хороший код с точки зрения эффективности. А в С++ в ряде мест используется магия слов и понятий, затуманивающих явления. Те же ссылки невозможно реализовать без указателей в общем случае. Более того, у них все свойства указателей де-факто сохраняются. При этом FAQ пишет такие вещи как «Reference IS Object», что просто улыбка с лица не сходит.
Если нужна эффективная реализация (с точки зрения максимальной отдачи от железа)- используйте ассемблер... меня раздражает другое какого хрена тыкают в реализацию даже в том случае , когда исходная задача не формулируется в низкоуровневых моделях.. лично я вижу одно обьяснение этому  - тяжелое наследие прошлого...
+1

PS. А ссылки нельзя в общем случае реализовать без использования "указателей", а точнее адресов, но верно и другое - семантику ссылок нельзя реализовать используя ТОЛЬКО указатели.
« Последнее редактирование: Март 25, 2013, 03:25:16 pm от valexey_u »
Y = λf.(λx.f (x x)) (λx.f (x x))

Berserker

  • Sr. Member
  • ****
  • Сообщений: 254
    • Просмотр профиля
Re: C++ инициализация ссылок
« Ответ #107 : Март 25, 2013, 06:44:40 pm »
Цитировать
Если нужна эффективная реализация (с точки зрения максимальной отдачи от железа)- используйте ассемблер... меня раздражает другое какого хрена тыкают в реализацию даже в том случае , когда исходная задача не формулируется в низкоуровневых моделях.. лично я вижу одно обьяснение этому  - тяжелое наследие прошлого...
Значит все игры и ресурсоёмкие приложения, включая браузеры, нужно писать на ассемблере? Вы попишите немного, поотлаживайте. Потом скажите, какой там коэффициент полезного действия и при чём тут ассемблер, если С++ включает в себя максимальное число возможностей, присутствующих исключительно с целью контроля эффективности.

DddIzer

  • Гость
Re: C++ инициализация ссылок
« Ответ #108 : Март 25, 2013, 07:17:43 pm »
Цитировать
Если нужна эффективная реализация (с точки зрения максимальной отдачи от железа)- используйте ассемблер... меня раздражает другое какого хрена тыкают в реализацию даже в том случае , когда исходная задача не формулируется в низкоуровневых моделях.. лично я вижу одно обьяснение этому  - тяжелое наследие прошлого...
Значит все игры и ресурсоёмкие приложения, включая браузеры, нужно писать на ассемблере? Вы попишите немного, поотлаживайте. Потом скажите, какой там коэффициент полезного действия и при чём тут ассемблер, если С++ включает в себя максимальное число возможностей, присутствующих исключительно с целью контроля эффективности.
Дешевая патетика.. - не все "игры и приложения".. а критические по производительности их части. Не вижу большого смысла в этих "максимальных возможностях" - если описание САМОГО ЯП не гарантирует их эффективную реализацию.. так... гребанные танцульки вокруг идолища, да срач на форумах... как пример... та же xds... при гораздо меньших данных для оптимизации на высокоуровневых задачах , обеспечивающая одинаковую производительность с лучшими компиляторами си того времени...

Valery Solovey

  • Hero Member
  • *****
  • Сообщений: 509
    • Просмотр профиля
Re: C++ инициализация ссылок
« Ответ #109 : Март 26, 2013, 07:04:23 pm »
В терминах реального железа и ассемблера ссылка в большинстве случае будет выглядеть как ячейка с адресом.
Даже не с адресом, а со словом данных.
И этим идентична указателю. С этим никто не спорит. Но как конструкция С++ она довольно сильно отличается от указателя. Этими отличиями можно пользоваться во благо (я там выше писал, почему ссылки полезны). В том числе и тем, что ссылка инициализируется один раз.
Думаю, как конструкция она больше всего похожа на директивы. Это сущность периода компиляции, указание компилятору. Если бы я захотел сделать реализацию своего языка, то в нём бы это было именно так (но как в плюсах, естественно, не знаю).

Что же касается беспокойства относительно места хранения данных и способа доступа к ним через ссылку, то я бы объяснял это так. Если объект создаётся в куче, то для обращения к нему нужно знать его адрес в памяти. Хранением адреса занимается указатель. Поэтому, в данном случае без указателя не обойтись. Но плюсовый указатель сам по себе имеет родовые проблемы, своеобразное решение которых было найдено через сколько-то десятков лет после создания языка светлыми C++ головами. Этим решением оказалась эфемерная обёртка вокруг интерфейса доступа к данным. В частности, у указателя есть богатый интерфейс, через который можно обращаться к данным различными способами. А ссылка служит эфемерной оболчкой вокруг этого интерфейса, оставив только способы доступа, которые светлые головы посчитали уместными, и сокрыв остальные.

Таким образом, если функция из внешней библиотеки возвращает данные, сохранённые в динамической памяти, а здесь мы присваиваем результат функции ссылке, то во время компиляции будет предусмотрено выделение памяти на стеке для указателя. Однако, поскольку указатель не объявлен в тексте программы, то доступа к нему нет. Но зато была объявлена ссылка, и на этапе компиляции проверяются способы доступа к ссылке, и если они корректны, то доступ переадесуется безымянному указателю.

Valery Solovey

  • Hero Member
  • *****
  • Сообщений: 509
    • Просмотр профиля
Re: C++ инициализация ссылок
« Ответ #110 : Март 26, 2013, 07:06:34 pm »
Ну и FFFFFUUUUUUUUUU этот ваш С++ о_О
   :D Geniepro ---  вы прям как животное (делаете то что нравится, работаете на том что нравится...)
Насчёт животных не скажу, но ставить правильные цели и добиваться их - признак счастливого человека.

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: C++ инициализация ссылок
« Ответ #111 : Март 26, 2013, 07:18:27 pm »
Думаю, как конструкция она больше всего похожа на директивы. Это сущность периода компиляции, указание компилятору. Если бы я захотел сделать реализацию своего языка, то в нём бы это было именно так (но как в плюсах, естественно, не знаю).
Собственно любой ЯВУ отличает именно то, что в нем есть то, что затем не отображается в машкод. Ну, например типы (их в машкоде просто нет) и все что с ними связано (например проверки валидности приведения типов на этапе компиляции).
Y = λf.(λx.f (x x)) (λx.f (x x))

DddIzer

  • Гость
Re: C++ инициализация ссылок
« Ответ #112 : Март 28, 2013, 10:40:00 am »
Ну и FFFFFUUUUUUUUUU этот ваш С++ о_О
   :D Geniepro ---  вы прям как животное (делаете то что нравится, работаете на том что нравится...)
Насчёт животных не скажу, но ставить правильные цели и добиваться их - признак счастливого человека.
С этой фразой согласен... вообще.. не очень понимаю только как она следует из оригинальной фразы (Geniepro ), в особенности  торкает слово "правильные"  :D  ;)

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: C++ инициализация ссылок
« Ответ #113 : Март 28, 2013, 10:55:37 am »
С этой фразой согласен... вообще.. не очень понимаю только как она следует из оригинальной фразы (Geniepro ), в особенности  торкает слово "правильные"  :D  ;)

Цитировать
— Почти все люди говорят себе, что поступают правильно ... . Но это не поднимает их над заурядностью.
http://www.fanfics.ru/read.php?id=40982&chapter=69
Y = λf.(λx.f (x x)) (λx.f (x x))

DddIzer

  • Гость
Re: C++ инициализация ссылок
« Ответ #114 : Март 28, 2013, 11:17:06 am »
С этой фразой согласен... вообще.. не очень понимаю только как она следует из оригинальной фразы (Geniepro ), в особенности  торкает слово "правильные"  :D  ;)

Цитировать
— Почти все люди говорят себе, что поступают правильно ... . Но это не поднимает их над заурядностью.
http://www.fanfics.ru/read.php?id=40982&chapter=69
ерунда... цель оценок этого уровня.. не поднятие над заурядностью, но достижение консенсуса ( либо собственным эго, либо мнением социума ).

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: C++ инициализация ссылок
« Ответ #115 : Март 28, 2013, 11:33:52 am »
Цитировать
Если нужна эффективная реализация (с точки зрения максимальной отдачи от железа)- используйте ассемблер... меня раздражает другое какого хрена тыкают в реализацию даже в том случае , когда исходная задача не формулируется в низкоуровневых моделях.. лично я вижу одно обьяснение этому  - тяжелое наследие прошлого...
Значит все игры и ресурсоёмкие приложения, включая браузеры, нужно писать на ассемблере? Вы попишите немного, поотлаживайте. Потом скажите, какой там коэффициент полезного действия и при чём тут ассемблер, если С++ включает в себя максимальное число возможностей, присутствующих исключительно с целью контроля эффективности.

Замечу, что обсуждаемые тут ссылки не являются по сути таковой возможностью, точнее ссылки они в основном не про эффективность, а про целостность и удобство (не синтаксическое удобство - лично я не вижу никакой разницы между написанием a.foo и a->foo, собственно я несколько лет на плюсах писа без ссылок вообще, и не было проблем ни с производительностью (хотя приложения были именно что про производительность) ни с синтаксисом проблем не было - авторазименовывание нафиг не нужно. А вот с нулевыми указателями как раз проблемы были :-) ).

C++ язык действительно высокого уровня. То есть он уровнем выше той же java. Это выражается в том, что в нем возможно создание собственных абстракций, так сказать, высшего порядка. В частности в C++ можно при желании создать конструкции для полноценного паттерн-матчинга.

И именно в сочетании такой вот высокоуровневости с возможностью перекладывать битики с байтиками, и состоит прелесть С++.
Y = λf.(λx.f (x x)) (λx.f (x x))

DddIzer

  • Гость
Re: C++ инициализация ссылок
« Ответ #116 : Март 28, 2013, 11:43:07 am »

Замечу, что обсуждаемые тут ссылки не являются по сути таковой возможностью, точнее ссылки они в основном не про эффективность, а про целостность и удобство (не синтаксическое удобство ...
В том  то и дело, что не смотря на понимание этого , даже вы спустились до уровня конкретной  реализации и "эффективности".. про форумы си- шников я вообще молчу...(чтобы не писать кипятком)...

Berserker

  • Sr. Member
  • ****
  • Сообщений: 254
    • Просмотр профиля
Re: C++ инициализация ссылок
« Ответ #117 : Март 28, 2013, 12:30:59 pm »
Цитировать
а про целостность и удобство
Если уж возвращаться к оригинальному заголовку темы, то меня интересовал лишь один вопрос: почему ссылки нельзя изменять? Выяснилось, что физически компиляторы изменение поддерживают, а запрет возник из-за прихоти создателя языка и не имеет под собой никаких оснований.

После этого поступили возражения по поводу того, что ссылки — это псевдонимы и что их в принципе менять нельзя, что, конечно же, неправда. Именно поэтому я был вынужден спуститься ниже и напомнить, что ссылки всё же указатели на физическом уровне, а возможность установки единожды используется компилятором исключительно для оптимизаций. Пример такой оптимизации локальных ссылок Вы и привели, Алексей.

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

Я даже скажу более, ссылка — не псевдоним с логической точки зрения.

vector<int> &a = rand() % 100 >= 50 ? b : c;
Это чистой воды ветвление. Почему же нельзя использовать if/else?

Ну и напоследок. Изменение ссылок не влияет на их свойство быть не NULL (хрупкое, конечно, но свойство).

Кстати, те же итераторы сделаны через указатели. Не сложно вызвать какой-нибудь find на пустой коллекции, разыменовать его и привязать объект к ссылке. Будет чистой воды NULL-ссылка в самом что ни на есть корректном коде.

P.S. Нужно вместо UB использовать PB — предсказуемое поведение в реальных реализациях :)

DddIzer

  • Гость
Re: C++ инициализация ссылок
« Ответ #118 : Март 28, 2013, 12:39:34 pm »

Если уж возвращаться к оригинальному заголовку темы, то меня интересовал лишь один вопрос: почему ссылки нельзя изменять? Выяснилось, что физически компиляторы изменение поддерживают, а запрет возник из-за прихоти создателя языка и не имеет под собой никаких оснований.

Имхо : плохой подход... это все равно что в жавке.. отвечая на вопрос почему строки иммутабельные..  вы лезете в реализацию оных...  - нет, ответ на этот вопрос - определение яп.. - просто по тому, что  так ПОСТАНОВИЛИ , что жабостроки иммутабельные... - это заложено в язык (а какими низкоуровневыми механизмами это будет обеспечиваться - пофиг - разумеется, если язык их не определяет )

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: C++ инициализация ссылок
« Ответ #119 : Март 28, 2013, 01:06:27 pm »
Цитировать
а про целостность и удобство
Если уж возвращаться к оригинальному заголовку темы, то меня интересовал лишь один вопрос: почему ссылки нельзя изменять? Выяснилось, что физически компиляторы изменение поддерживают, а запрет возник из-за прихоти создателя языка и не имеет под собой никаких оснований.
Очевидно, что это не так.

Во-первых: я явно привел пример когда видно, что внутренняя реализация ссылок и указателей может быть различна - в случае gcc у них разные UB в случае const_cast'a.
Во-вторых: аргументы влада.
В-третьих: ссылка гарантирует что переменная валидна. Никаких нулей.

После этого поступили возражения по поводу того, что ссылки — это псевдонимы и что их в принципе менять нельзя, что, конечно же, неправда. Именно поэтому я был вынужден спуститься ниже и напомнить, что ссылки всё же указатели на физическом уровне, а возможность установки единожды используется компилятором исключительно для оптимизаций. Пример такой оптимизации локальных ссылок Вы и привели, Алексей.
Я не очень понимаю различие между реализацией и, гм, оптимизацией реализации :-) В принципе полагаю возможно как минимум часть семантики (если не всю семантику) ссылок реализовать через простое копирование объекта (без вызовов конструкторов, тупо memcpy). И это не будет противоречить стандарту.

Я просто прошу взглянуть свежим и трезвым взглядом на проблему. Правило одного присваивания — это сфера функциональных языков, не имеющая смысла в императивных.
Эмм.. Что за домыслы? Иммутабельность естественно имеет смысл в императивных языках. Функциональность довольно таки ортогональна иммутабельности :-) Впрочем, задам ка я вопрос - какое основное отличие функционального языка от императивного? Вот прям основное-основное.

То есть если X — это ссылка на объект типа файловой системы, то никакой причины запретить динамически подменять реализацию файловой системы нет.
Э? При чем тут реализация?

Я даже скажу более, ссылка — не псевдоним с логической точки зрения.
vector<int> &a = rand() % 100 >= 50 ? b : c;Это чистой воды ветвление. Почему же нельзя использовать if/else?
Конечно это ветвление. И конечно же это не отменяет тот факт, что "a" тут является псевдонимом как и обычно :-) some& foo = expr;  -- тут foo является псевдонимом для результата выражения expr. const int& foo = 42; -- частный случай этого. Тут просто выражение тривиально. Кто сказал что псевдонимы могут быть только детерминированными? :-)

Тернарный оператор - это выражение, так что не вижу никаких противоречий. А вот if..else - это зачем-то statement. Поэтому увы-с, не взлетит.

Ну и напоследок. Изменение ссылок не влияет на их свойство быть не NULL (хрупкое, конечно, но свойство).
Покажи пожалуйста, ну, например на примере java, как ты собираешься бороться с нулями в изменяемых ссылках. То есть чтобы гарантированно, и не зависило от кривости рук программера.

Ну, например на том же примере твоем: vector<int> &a = rand() % 100 >= 50 ? b : c;
Пусть тут будет: 1) if..else. 2) не будет лишних инициализаций.

Кстати, те же итераторы сделаны через указатели. Не сложно вызвать какой-нибудь find на пустой коллекции, разыменовать его и привязать объект к ссылке. Будет чистой воды NULL-ссылка в самом что ни на есть корректном коде.
Нет, итератеры не сделаны через указатели :-) И пусть тебя не смущает разименовывание и стрелочки для доступа к потрохам - это обычные объекты :-) Каждый указатель можно трактовать как итератор, но не каждый этератор является указателем. Вообще, с точки зрения С++, указатели - это такие кривые и недоделанные, кастрированные, итераторы.

А то что ты описал - не будет NULL-ссылкой. Будет UB чистой воды (причем по двум разным причинам одновременно). И нет, это не корректный код. :-)
Y = λf.(λx.f (x x)) (λx.f (x x))