【发布时间】:2015-07-27 01:40:50
【问题描述】:
这可能更多是关于计算机体系结构的问题,而不是 C++ 本身的问题,但我想知道在理论上是否可以在不使用 C++ 等语言中的指针的情况下实现传递引用。
下面是三个具有相似功能和结构的代码示例。
//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;
}
我的猜测是第一个版本中的增量函数直接访问全局变量,没有任何指针。第二个版本在函数的堆栈帧中分配一个指向局部变量的指针并间接访问它。从快速搜索来看,第三个版本的实现(无论如何在优化之前)显然与第二个版本完全一样。来源:How is reference implemented internally?
但是理论上(甚至在实践中,经过一些编译器优化后),第三个函数可以直接访问它自己的堆栈框架之外的局部变量而不需要指针?或者这种行为是全局变量独有的,因为它们在内存中的位置是静态的?
我问这个是因为我认为创建和取消引用指针应该占用少量的时间和内存。在诸如传递十几个引用的深度递归函数之类的东西中,时间和内存可能会加起来。
附:我还应该特别提到内联函数,因为它们甚至不会生成新的堆栈帧。即,如果函数是 inline int increment(int*) 和 inline int increment(int&),版本 2 和 3 的汇编代码会有所不同,还是编译器会在这种情况下优化掉指针?
【问题讨论】:
-
版本 3 可能会内联函数
标签: c++ pass-by-reference pass-by-pointer