Когда ссылка передается функции, компилятор, вероятно, реализует ее как скрытый указатель - поэтому изменение типа не имеет значения.
Когда ссылка создается и используется локально, компилятор можетбыть достаточно умным, чтобы знать, к чему он относится, и рассматривать его как псевдоним указанной переменной.Если переменная оптимизирована для регистра, компилятор будет знать, что ссылка также является тем же регистром.
Указатель всегда должен указывать на область памяти.Даже на нечетной архитектуре, которая дает места памяти для его регистров, кажется маловероятным, что компилятор поддержит такую операцию.
Редактировать: В качестве примера, вот сгенерированный код от MicrosoftC ++ с оптимизацией.Код для указателя и переданной ссылки идентичны.Параметр, передаваемый по значению, по какой-то причине не попал в регистр, даже когда я переставил список параметров.Тем не менее, после того, как значение было скопировано в регистр, и локальная переменная, и локальная ссылка использовали один и тот же регистр без перезагрузки.
void __fastcall test(int i, int * ptr, int & ref)
{
_i$ = 8 ; size = 4
_ref$ = 12 ; size = 4
?test@@YIXHPAHAAH@Z PROC ; test, COMDAT
; _ptr$ = ecx
; 8 : global_int1 += *ptr;
mov edx, DWORD PTR [ecx]
; 9 :
; 10 : global_int2 += ref;
mov ecx, DWORD PTR _ref$[esp-4]
mov eax, DWORD PTR _i$[esp-4]
add DWORD PTR ?global_int1@@3HA, edx ; global_int1
mov edx, DWORD PTR [ecx]
add DWORD PTR ?global_int2@@3HA, edx ; global_int2
; 11 :
; 12 : int & ref2 = i;
; 13 : global_int3 += ref2;
add DWORD PTR ?global_int3@@3HA, eax ; global_int3
; 14 :
; 15 : global_int4 += i;
add DWORD PTR ?global_int4@@3HA, eax ; global_int4