Передача по значению является наиболее простой формой передачи. И все реализовано в терминах передачи по значению в конце.
Если вы спрашиваете о том, что на самом деле происходит , когда вызывается функция и аргументы передаются по значению, это зависит от платформы. Каждая платформа имеет свое собственное «соглашение о вызовах». В большинстве случаев происходит то, что первые несколько аргументов хранятся в регистрах процессора. Все оставшиеся аргументы будут храниться в предопределенном месте в стеке фрейма вызываемой функции, аналогично локальным переменным. (То, как локальные переменные хранятся в кадре стека, определяется компилятором во время компиляции.) Поэтому, когда вызывается функция, все аргументы, которые должны быть сохранены в стеке, копируются туда; и любые аргументы, которые должны быть сохранены в регистрах, загружаются туда. Затем управление передается функции.
Что касается передачи по ссылке, если в языке есть указатели, передача по ссылке может быть выполнена путем передачи указателей по значению. Компилятор может просто выполнить этап предварительной обработки, где он «исключает» передачу по ссылке, выполняя следующий перевод:
- Для каждого параметра функции, переданного по ссылке, он заменяет его указателем на тип, переданный по значению (например,
void func(int &foo)
-> void func(int *foo)
)
- Для каждого использования этого параметра передачи по ссылке внутри этой функции, измените его на явное разыменование указателя (например,
foo
-> *foo
) (за исключением того, что если он снова передается по ссылке, don Обращайтесь)
- Каждый раз, когда вызывается эта функция, независимо от того, что передается в переменную pass-by-reference, я беру ее адрес явно (например,
func(bar)
-> func(&bar)
)