Компилятор и ссылка С++
- Войдите на сайт для отправки комментариев
Пт, 27/09/2019 - 22:26
Как работает компилятор с указателем ясно, он просто размещает его в памяти; указатель есть объект.
А как он со ссылкой поступает, как он хранится в микроконтроллере например. Ну вот допустим некая переменная в стеке (динамическая). И мы к ней через ссылку стучимся. Где эта ссылка в МК? Ведь она не есть объект.
Или я куда-то не туда думаю...
Ссылка и есть указатель, только не его значение, а адрес. Тоже, разумеется "хранится" в памяти.
Адреса памяти: [ 0 1 2 ... 2040 ... 2047 ]
Её содержимое: [ 00 00 00 ... FF ... 00 ]
Например, по адресу 2040 у нас создаётся byte x = 0xff, тогда: х = 0xff, &x = 2040.
Или же, по этому адресу создаётся указатель, тогда у него тоже будет два значения - его собственно адрес, и в этих байтах по этому адресу хранится другой адрес, туда, куда он указывает.
Программист пишет исходник, в частности на Си,А процессор работает в коде. Поэтому указатели или ссылки интересуют только компилятор и никто больше. Вот компилятор и решает выделить место в ОЗУ для новой переменной или же взять имеющее. Указатель указывает на место где расположена переменная, и под указатель выделяется место в ОЗУ. А ссылка это псевдоним и место под переменную в ОЗУ не надо выделять.
При написании программ на С++ программист использует и ссылки и указатели. Вот по какому физическому адресу они размещаются в большинстве случаев программиста не особо интересует. Хотя иногда и может.
А ссылка это вовсе не псевдоним, а почти то же самое что и указатель, только синтаксис немного другой и есть некоторые ограничения в использовании.
asam. Для работы с любой переменной что в языке Си , что в других языках нужен указатель на эту переменную. Только в языке Си указатель прописался явно. Ссылка прописалась как инструмент экономии памяти, Позже прилетела и правая ссылка по той же причине.
Запомни или запиши .
Слушаюсь, мой Повелитель)).
Указатель указывает на место
Да с указателями все ясно, вопрос не об указателях, а о ссылках. Я понимаю, что ссылка - это КАК-БЫ константный указатель на некую переменную, который автоматически разименовывается при вызове. Но только КАК-БЫ. У ссылки нет адреса, она не объект. И мне стало любопытно, каким образом компилятор работает именно со ссылкой.
Да как, как... сует её константой в объектный код.
Да как, как... сует её константой в объектный код.
И эта константа....? что она делает,на какую инструкцию ссылается....?
Да как, как... сует её константой в объектный код.
И эта константа....? что она делает,на какую инструкцию ссылается....?
Вопрос снимаю в связи с его (вопроса) глупостью. Туман стал менее густым. sadman41,спасибо.
Переспал с осмыслением. Как я это понял (на пальцах):
объектный код, дойдя до обращения по ссылке, выполняет некий набор инструкций, с помощью которых а) - определяет адрес переменной; б) - собственно манипуляции с переменной. Все это без выделения дополнительной памяти.
Так ли?
Подпишусь
ОФФТОП
Переспал с осмыслением. Как я это понял (на пальцах):
объектный код, дойдя до обращения по ссылке, выполняет некий набор инструкций, с помощью которых а) - определяет адрес переменной; б) - собственно манипуляции с переменной. Все это без выделения дополнительной памяти.
Так ли?
""... Вот компилятор и решает выделить место в ОЗУ для новой переменной или же взять имеющее... ""
Походу компилятор вскрывать придется... а оно (вскрытие) покажет...
сори за оффтоп.
Подпишусь
Лучше носом ткните, где почитать?, "подпишусь" в Вашем исполнении звучит как издевка).
Лучше носом ткните, где почитать?, "подпишусь" в Вашем исполнении звучит как издевка).
"Подпишусь" - означает, что человеку эта тема интересна и он хочет получать уведомления при появлении новых постов в теме, а сказать нового по вопросу он не имеет. И так поступают многие...
следить можно в "мой профиль"-> "следить"
Гриша
Конечно нового не имеет, ведь как я понимаю, Евгений Петрович как раз и разрабатывает теорию компиляторов.
kolyn
Почитать можно в документации по gcc и в стандарте си, погуглил пару минут, но вот так сходу определённое место ткнуть не нашёл. Ещё можно в исходниках gcc, но наверное, пока рановато.
Вы пытаетесь применить "вышележащий уровень" к более низколежащему. Да, на уровне си есть все эти ссылки, строки, объекты. Но компилятор при трансляции в объектник заменяет это всё на более низкие примитивы ассемблера. Объектный код не определяет адрес переменной, он его уже знает, после трансляции, либо узнаёт его в ходе выполнения, до обращения к переменной, на этапе выделения памяти менеджером памяти.
Если ещё упростить, то объектный код, в том месте, где "обращение по ссылке", может выполнять либо команду ассемблера "загрузить значение" mov r1, var; либо команду "загрузить адрес" lea r1, var. В первом случае в r1 попадёт (условно, из моего примера в #1) 0xff, во втором - 2040. В любом случае, что-то физическое, где хранится переменная, всегда есть, будь то константа в коде или несколько байт в оперативной памяти.
Что делает компилятор. Выделяет память с размерностью int и где-то у себя строит таблицу переменных переменная a с типом инт и находится там-то(там-то и есть указатель)
Усложним
Теперь к предыдущему варианту компилятор выделяет память для переменой b и строит новую строку в таблице переменная b c типом int и находится в другом там-то(новый указатель).
Ну и наконец
Здесь компилятор не выделяет память в ОЗУ но добавляет в таблицу строку переменая b с размерностью int находится там-то, но указатель нахождения берется из переменой a. Как будто что a , что b одно и тоже в программном смысле.
А смысл эта пляска приобретает при объявлении и вызове функций. Без функций этой пляски можно избежать.
Вы пытаетесь применить "вышележащий уровень" к более низколежащему.
Я попытался действия "низлежащего" сформулировать "человечьими" словами, максимально утрируя... И понять,правильно ли я думаю. Судя по
Если ещё упростить, то объектный код, в том месте, где "обращение по ссылке", может выполнять либо команду ассемблера "загрузить значение" mov r1, var; либо команду "загрузить адрес" lea r1, var. В первом случае в r1 попадёт (условно, из моего примера в #1) 0xff, во втором - 2040. В любом случае, что-то физическое, где хранится переменная, всегда есть, будь то константа в коде или несколько байт в оперативной памяти.
думаю правильно
Дело в том, что на уровне машинных кодов вообще нет никаких переменных - только адреса байтов и их значения. Можно загрузить либо то, либо другое в регистры и что-нибудь с ними сделать, потом выгрузить обратно в память. Ну, либо скопировать из памяти в другую ячейку памяти.
Что мешает написать минимальный код и глянуть в листинге что наваял компилятор ? Думаю сильно будет зависеть от заданного уровня оптимизации.
самое главное отличие указателя от ссылки, то что указатель может быть нулевым, а ссылка не может ссылаться на пустоту.
то есть вот так написать можно
int *a = NULL;
потом указателю можно переприсвоить адрес другой переменной, и не обязательно int.
а от так нельзя
int &a;
ссылка должна сразу ссылаться на что-то и переприсвоить ей больше ничего нельзя.
int b;
int &a = b;
теперь переменные a и b - псевдонимы, одна и та же ячейка памяти с разными именами.
кстати, ссылка в параметрах функции - совсем отдельная песня. :)
Пример с декомпиляцией тут: https://stackoverflow.com/questions/21145171/c-references-and-pointers-at-the-compiler-level
Но, вообще, как я понимаю, действия компилятора не стандартизованы и он может делать красиво разными способами (применяя различные паттерны), поэтому вопрос, в принципе, не имеет однозначного ответа.
Но, оговорюсь еще раз - я не профессионал и образован не совсем в этой области, но где-то на неокортексе когда-то читанное застряло.
Спасибо всем, все более-менее ясно.
Я ведь "не настоящий сварщик" и вряд ли им стану. Занятие программированием - просто попытка отложить старческую деменцию;).
думаю, что часть ответа можно найти в ВИКИ RISC
и почитать о "Гарвардская архитектура" хотя бы тут
Как работает компилятор с указателем ясно, он просто размещает его в памяти; указатель есть объект.
А как он со ссылкой поступает?
ИМХО: коротко и ясно и по теме :))))
Дело в том, что на уровне машинных кодов вообще нет никаких переменных - только адреса байтов и их значения.
полагаю, что и абсолютно правильно. Есть иные мнения?
UPD/
не помню, как правильно называются "инструкции в МК", которые указывают АЛУ что сделать с байтами... сколько помню - АЛУ в МК может только "складывать" и "сдвигать" даже вычитание делается через сложение... давно это было почитай "не знал, да еще и забыл"... речь идет о RISC от ATMEL с Гарвардской архитектурой.
ИМХО ответ на первый пост кроется в железе и его архитектуре и немного в компиляторе, который создает программный код под это железо... учитывая что RISC and ARM только похожи и имеют разные инструкции и регистры и их количество... в общем куда наша ссылка попадет зависит от конкретного случая, точнее от того как ее компилятор интерпретирует. А "в общем" ответы выше уже даны, остались нюансы. ИМХО - ничего не утверждаю (знаний маловато)
Есть атом железа. Логично предположить что он будет входить в состав какой-то железаки. Но не гарантии того что он не станет органическим соединением ,к примеру, гемоглобином.
Насколько я себе представляю, ссылка - это адрес некоторой ячейки в памяти.
Всегда.
Если выделить память и в эту память записать данный адрес - будет указатель.
Но обратиться к ячейке можно разными способами, не обязательно посредством переменной типа указатель. Вот для иных способов обращения к ячейке памяти (через адрес в регистрах, через адрес в сегменте кода и пр.) и используется ссылка. А какой именно способ доступа будет применен, решает компилятор.
Процессор поддерживает несколько разных типов адресации, указатель - лишь один из них.
Есть атом железа. Логично предположить что он будет входить в состав какой-то железаки.
парадокс, но подавляющее число атомов железа на планете Земля входят в состав соединений, видом и свойствами никак не напоминающие железяку :))))
Процессор поддерживает несколько разных типов адресации, указатель - лишь один из них.
Точно. Вот только ссылки среди этих типов нет. Эта сущность времени компиляции. Компилятор кончил - ссылки превратились в один из поддерживаемых процессором типов адресации. Вывод - ссылок не существует, фикция это, специально придуманная чтоб программерам мозги пудрить. Мы ответили взаимностю - игнорим их )))) Почти все, почти всегда ;) Очень ситуация мне сказку про бога напоминает, кто то придумал, он громовержец - на деле электричество. Радуга - это знак. А на деле оптика. По воде ходил - а там ветер воду отогнал. И так что не проверь - сводится к квантовой механике;) Говорят все им создано и на нем держится. А на дели и без него ОК. Придумали рай , только уверуй и не греши, сылками пиши, опасными указателями не греши. Но некоторые таки верят, и говорят помогает, говорят на благо мол.
ПС. Это ж ветка холиварная, я не перепутал?
ППС. На уровне процессора нечто отдаленно похожее на доступ к памяти по ссылке будет при работе через дескрипторную таблицу.
По теме, когдато порадовала доступностю https://habr.com/ru/post/348198/