Компилятор и ссылка С++

kolyn
Offline
Зарегистрирован: 18.01.2019

Как работает компилятор с указателем ясно, он просто размещает его в памяти; указатель есть объект. 

А как он со ссылкой поступает, как он хранится в микроконтроллере например. Ну вот допустим некая переменная в стеке (динамическая). И мы к ней через ссылку стучимся. Где эта ссылка в МК? Ведь она не есть объект.

Или я куда-то не туда думаю...

negavoid
Offline
Зарегистрирован: 09.07.2016

Ссылка и есть указатель, только не его значение, а адрес. Тоже, разумеется "хранится" в памяти.

Адреса  памяти: [ 0  1  2  ... 2040 ... 2047 ]

Её содержимое: [ 00 00 00 ... FF ... 00 ]

Например, по адресу 2040 у нас создаётся byte x = 0xff, тогда: х = 0xff, &x = 2040.

Или же, по этому адресу создаётся указатель, тогда у него тоже будет два значения - его собственно адрес, и в этих байтах по этому адресу хранится другой адрес, туда, куда он указывает.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

kolyn пишет:
Или я куда-то не туда думаю...

Точно не туда. Запомни или запиши . Программист пишет исходник, в частности на Си,А процессор работает в коде. Поэтому указатели или ссылки интересуют только компилятор и никто больше. Вот компилятор и решает выделить место в ОЗУ для новой переменной или же взять имеющее. Указатель указывает на место где расположена переменная, и под указатель выделяется место в ОЗУ. А ссылка это псевдоним и место под переменную в ОЗУ не надо выделять.

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

qwone пишет:

 Программист пишет исходник, в частности на Си,А процессор работает в коде. Поэтому указатели или ссылки интересуют только компилятор и никто больше. Вот компилятор и решает выделить место в ОЗУ для новой переменной или же взять имеющее. Указатель указывает на место где расположена переменная, и под указатель выделяется место в ОЗУ. А ссылка это псевдоним и место под переменную в ОЗУ не надо выделять.

 

При написании программ на  С++ программист использует и ссылки и указатели. Вот по какому физическому адресу они размещаются в большинстве случаев программиста не особо интересует. Хотя иногда и может.

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

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

asam. Для работы с любой переменной что в языке Си , что в других языках нужен указатель на эту переменную. Только в языке Си указатель прописался явно.  Ссылка прописалась как инструмент экономии памяти, Позже прилетела и правая ссылка по той же причине.

kolyn
Offline
Зарегистрирован: 18.01.2019

qwone пишет:

Запомни или запиши . 

Слушаюсь, мой Повелитель)).

qwone пишет:

Указатель указывает на место  

Да с указателями все ясно, вопрос не об указателях, а о ссылках. Я понимаю, что ссылка - это КАК-БЫ константный указатель на некую переменную, который автоматически разименовывается при вызове. Но только КАК-БЫ. У ссылки нет адреса, она не объект. И мне стало любопытно, каким образом компилятор работает именно со ссылкой.

sadman41
Offline
Зарегистрирован: 19.10.2016

Да как, как... сует её константой в объектный код.

kolyn
Offline
Зарегистрирован: 18.01.2019

sadman41 пишет:

Да как, как... сует её константой в объектный код.

И эта константа....? что она делает,на какую инструкцию ссылается....?

 

kolyn
Offline
Зарегистрирован: 18.01.2019

kolyn пишет:

sadman41 пишет:

Да как, как... сует её константой в объектный код.

И эта константа....? что она делает,на какую инструкцию ссылается....?

 

Вопрос снимаю в связи с его (вопроса) глупостью. Туман стал менее густым. sadman41,спасибо.

 

kolyn
Offline
Зарегистрирован: 18.01.2019

Переспал с осмыслением. Как я это понял (на пальцах):

объектный код, дойдя до обращения по ссылке, выполняет некий набор инструкций, с помощью которых а) - определяет адрес переменной; б) - собственно манипуляции с переменной. Все это без выделения дополнительной памяти.

Так ли?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Подпишусь

Гриша
Offline
Зарегистрирован: 27.04.2014

ОФФТОП

kolyn пишет:

Переспал с осмыслением. Как я это понял (на пальцах):

объектный код, дойдя до обращения по ссылке, выполняет некий набор инструкций, с помощью которых а) - определяет адрес переменной; б) - собственно манипуляции с переменной. Все это без выделения дополнительной памяти.

Так ли?

qwone пишет:

""... Вот компилятор и решает выделить место в ОЗУ для новой переменной или же взять имеющее... ""

Походу компилятор вскрывать придется... а оно (вскрытие) покажет...

сори за оффтоп.

kolyn
Offline
Зарегистрирован: 18.01.2019

ЕвгенийП пишет:

Подпишусь

Лучше носом ткните, где почитать?, "подпишусь" в Вашем исполнении звучит как издевка).

 

Гриша
Offline
Зарегистрирован: 27.04.2014

kolyn пишет:

Лучше носом ткните, где почитать?, "подпишусь" в Вашем исполнении звучит как издевка).

"Подпишусь" - означает, что человеку эта тема интересна и он хочет получать уведомления при появлении новых постов в теме, а сказать нового по вопросу он не имеет. И так поступают многие...

следить можно в "мой профиль"-> "следить"

negavoid
Offline
Зарегистрирован: 09.07.2016

Гриша

Конечно нового не имеет, ведь как я понимаю, Евгений Петрович как раз и разрабатывает теорию компиляторов.

kolyn

Почитать можно в документации по gcc и в стандарте си, погуглил пару минут, но вот так сходу определённое место ткнуть не нашёл. Ещё можно в исходниках gcc, но наверное, пока рановато.

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

Если ещё упростить, то объектный код, в том месте, где "обращение по ссылке", может выполнять либо команду ассемблера "загрузить значение" mov r1, var; либо команду "загрузить адрес" lea r1, var. В первом случае в r1 попадёт (условно, из моего примера в #1) 0xff, во втором - 2040. В любом случае, что-то физическое, где хранится переменная, всегда есть, будь то константа в коде или несколько байт в оперативной памяти.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016
int a=10;

Что делает компилятор. Выделяет память с размерностью int и где-то у себя строит таблицу переменных переменная a с типом инт и находится там-то(там-то и есть указатель)

Усложним 

int a=10;
int b=a;

Теперь к предыдущему варианту компилятор выделяет память для переменой b и строит новую строку в таблице переменная b c типом int и находится в другом там-то(новый указатель).

Ну и наконец 

int a=10;
int b=&a;

Здесь компилятор не выделяет память в ОЗУ но добавляет в таблицу строку переменая b с размерностью int находится там-то, но указатель нахождения берется из переменой a. Как будто что a , что b одно и тоже в программном смысле.

А смысл эта пляска приобретает при объявлении и вызове функций. Без функций этой пляски можно избежать.

kolyn
Offline
Зарегистрирован: 18.01.2019

negavoid пишет:

Вы пытаетесь применить "вышележащий уровень" к более низколежащему.

Я попытался действия "низлежащего" сформулировать "человечьими" словами, максимально утрируя... И понять,правильно ли я думаю. Судя по 

negavoid пишет:

Если ещё упростить, то объектный код, в том месте, где "обращение по ссылке", может выполнять либо команду ассемблера "загрузить значение" mov r1, var; либо команду "загрузить адрес" lea r1, var. В первом случае в r1 попадёт (условно, из моего примера в #1) 0xff, во втором - 2040. В любом случае, что-то физическое, где хранится переменная, всегда есть, будь то константа в коде или несколько байт в оперативной памяти.

думаю правильно

negavoid
Offline
Зарегистрирован: 09.07.2016

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

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

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

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

самое главное отличие указателя от ссылки, то что указатель может быть нулевым, а ссылка не может ссылаться на пустоту. 

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

int *a = NULL;

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

а от так нельзя 

int &a;

ссылка должна сразу ссылаться на что-то и переприсвоить ей больше ничего нельзя. 

int b;

int &a = b;

теперь переменные a и b - псевдонимы, одна и та же ячейка памяти с разными именами. 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

кстати, ссылка в параметрах функции - совсем отдельная песня. :) 

sadman41
Offline
Зарегистрирован: 19.10.2016

Пример с декомпиляцией тут: https://stackoverflow.com/questions/21145171/c-references-and-pointers-at-the-compiler-level

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

Но, оговорюсь еще раз - я не профессионал и образован не совсем в этой области, но где-то на неокортексе когда-то читанное застряло. 

kolyn
Offline
Зарегистрирован: 18.01.2019

Спасибо всем, все более-менее ясно.

Я ведь "не настоящий сварщик" и вряд ли им стану. Занятие программированием - просто попытка отложить старческую деменцию;).

Гриша
Offline
Зарегистрирован: 27.04.2014

думаю, что часть ответа можно найти в ВИКИ RISC

 и почитать о "Гарвардская архитектура" хотя бы тут 

kolyn пишет:

Как работает компилятор с указателем ясно, он просто размещает его в памяти; указатель есть объект. 

А как он со ссылкой поступает?

ИМХО: коротко и ясно и по теме :))))

negavoid пишет:

Дело в том, что на уровне машинных кодов вообще нет никаких переменных - только адреса байтов и их значения. 

полагаю, что и абсолютно правильно. Есть иные мнения? 

UPD/

не помню, как правильно называются "инструкции в МК", которые указывают АЛУ что сделать с байтами... сколько помню - АЛУ в МК может только "складывать" и "сдвигать" даже вычитание делается через  сложение... давно это было почитай "не знал, да еще и забыл"... речь идет о RISC от ATMEL  с Гарвардской архитектурой.

ИМХО ответ на первый пост кроется в железе и его архитектуре и немного в компиляторе, который создает программный код под это железо... учитывая что RISC and ARM  только похожи и имеют разные инструкции и регистры и их количество... в общем куда наша ссылка попадет зависит от конкретного случая, точнее от того как ее компилятор интерпретирует. А "в общем" ответы выше уже даны, остались нюансы. ИМХО - ничего не утверждаю (знаний маловато)  

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Есть атом железа. Логично предположить что он будет входить в состав какой-то железаки. Но не гарантии того что он не станет органическим соединением ,к примеру, гемоглобином.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Насколько я себе представляю, ссылка - это адрес некоторой ячейки в памяти.

Всегда.

Если выделить память и в эту память записать данный адрес - будет указатель. 

Но обратиться к ячейке можно разными способами, не обязательно посредством переменной типа указатель. Вот для иных способов обращения к ячейке памяти (через адрес в регистрах, через адрес в сегменте кода и пр.) и используется ссылка. А какой именно способ доступа будет применен, решает компилятор.

Процессор поддерживает несколько разных типов адресации, указатель - лишь один из них.

b707
Offline
Зарегистрирован: 26.05.2017

qwone пишет:

Есть атом железа. Логично предположить что он будет входить в состав какой-то железаки.

парадокс, но подавляющее число атомов железа на планете Земля входят в состав соединений, видом и свойствами никак не напоминающие железяку :))))

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

b707 пишет:
подавляющее число атомов железа на планете Земля входят в состав соединений, видом и свойствами никак не напоминающие железяку :))))
Бывает, чё :)

Logik
Offline
Зарегистрирован: 05.08.2014

andriano пишет:

Процессор поддерживает несколько разных типов адресации, указатель - лишь один из них.

Точно. Вот только ссылки среди этих типов нет.  Эта сущность времени компиляции. Компилятор кончил - ссылки превратились в один из поддерживаемых процессором типов адресации. Вывод - ссылок не существует, фикция это, специально придуманная чтоб программерам мозги пудрить. Мы ответили взаимностю - игнорим их )))) Почти все, почти всегда ;) Очень ситуация мне сказку про бога напоминает, кто то придумал, он громовержец - на деле электричество. Радуга - это знак. А на деле оптика. По воде ходил - а там ветер воду отогнал.  И так что не проверь - сводится к квантовой механике;)   Говорят все им создано и на нем держится. А на дели и без него ОК. Придумали рай , только уверуй и  не греши, сылками пиши,  опасными указателями не греши.  Но некоторые таки верят, и говорят помогает, говорят на благо мол.

ПС. Это ж ветка холиварная, я не перепутал?

ППС. На уровне процессора нечто отдаленно похожее на доступ к памяти по ссылке будет при работе через дескрипторную таблицу.

По теме, когдато порадовала доступностю https://habr.com/ru/post/348198/