Как компилятор реализует передачу по значению и передачу по ссылке? - PullRequest
0 голосов
/ 20 ноября 2011

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

Ответы [ 2 ]

3 голосов
/ 20 ноября 2011

Передача по значению является наиболее простой формой передачи. И все реализовано в терминах передачи по значению в конце.

Если вы спрашиваете о том, что на самом деле происходит , когда вызывается функция и аргументы передаются по значению, это зависит от платформы. Каждая платформа имеет свое собственное «соглашение о вызовах». В большинстве случаев происходит то, что первые несколько аргументов хранятся в регистрах процессора. Все оставшиеся аргументы будут храниться в предопределенном месте в стеке фрейма вызываемой функции, аналогично локальным переменным. (То, как локальные переменные хранятся в кадре стека, определяется компилятором во время компиляции.) Поэтому, когда вызывается функция, все аргументы, которые должны быть сохранены в стеке, копируются туда; и любые аргументы, которые должны быть сохранены в регистрах, загружаются туда. Затем управление передается функции.

Что касается передачи по ссылке, если в языке есть указатели, передача по ссылке может быть выполнена путем передачи указателей по значению. Компилятор может просто выполнить этап предварительной обработки, где он «исключает» передачу по ссылке, выполняя следующий перевод:

  • Для каждого параметра функции, переданного по ссылке, он заменяет его указателем на тип, переданный по значению (например, void func(int &foo) -> void func(int *foo))
  • Для каждого использования этого параметра передачи по ссылке внутри этой функции, измените его на явное разыменование указателя (например, foo -> *foo) (за исключением того, что если он снова передается по ссылке, don Обращайтесь)
  • Каждый раз, когда вызывается эта функция, независимо от того, что передается в переменную pass-by-reference, я беру ее адрес явно (например, func(bar) -> func(&bar))
2 голосов
/ 20 ноября 2011

Это полностью зависит от того, как компилятор обрабатывает переменные (что можно назвать «средой»).

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

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

В других средах потребуются другие подходы.

...