This might be more a question on computer architecture than on C++ itself, but I was wondering if pass-by-reference could theoretically be implemented without using pointers in a language like C++.
Here are three examples of code that have similar function and structure.
//Version 1: Uses global variable
#include <iostream>
int global_var = 0;
int increment(void) {return ++global_var;}
int main(void)
{
while (global_var < 100)
printf("Counter: %i\n", increment());
return 0;
}
//Version 2: Uses pass-by-pointer
#include <iostream>
int increment(int* ptr) {return ++(*ptr);}
int main(void)
{
int local_var = 0;
while (local_var < 100)
printf("Counter: %i\n", increment(&local_var));
return 0;
}
//Version 3: Uses pass-by-reference
#include <iostream>
int increment(int& ref) {return ++ref;}
int main(void)
{
int local_var = 0;
while (local_var < 100)
printf("Counter: %i\n", increment(local_var));
return 0;
}
My guess is that the increment function in the first version accesses the global variable directly, without any pointers. The second version allocates a pointer in the function's stack frame pointing to the local variable and access it indirectly. From a quick search, the third version is apparently implemented (before optimization anyway) exactly like the second version. Source: How is reference implemented internally?
But in theory (or even in practice, after optimization by some compiler), could the third function directly access the local variable outside its own stack frame without a pointer? Or is that behavior exclusive to global variables, since their locations in memory are static?
I ask this because I would think that creating and dereferencing pointers should take up a small amount of time and memory. In something such as a deep recursive function that passes around a dozen references, that time and memory could add up.
P.S. I should also specifically mention inline functions, seeing as they don't even generate new stack frames. i.e. Would the assembly code for versions 2 and 3 vary if the functions were inline int increment(int*)
and inline int increment(int&)
, or would the compiler just optimize away the pointer in that case?