提问者:小点点

C++11将变量引用为lvalues。 它们是真的“VAR”还是只是“别名”?


问题就在标题里。 如果我在C++11中有以下代码:

int a, b = 20;
int &ra = a;
ra = b;
std::cout << ra << std::endl;     //Prints 20

编译器是如何处理“RA”的,它是创建另一个var作为指针还是它只是一个别名,当编译器发现“RA”和说“a”是一样的?


共1个答案

匿名用户

是的。 而且,没有。 呵呵。 继续读下去。

这里有两层抽象在起作用,你应该试着理解这两层。

当您编写C++时,您正在描述一个程序。 你并不是在写指令让计算机执行。 那是编译器的工作。

在您的C++代码中,ra只是一个别名。 它不是“物体”。 操作引用的语法很少,这是经过深思熟虑的:我们应该将ra视为a; 这是同一个东西的两个名字。

即使当我们深入钻研语言时,我们也能观察到这一点。 给定以下函数:

int bar = 42;

int& foo()
{
   return bar;
}

…表达式foo()不是引用! 这让很多人大跌眼镜。 这是一个“int类型的lvalue”。 只是int,而不是int&。 它是一个表达式,用来“命名”您最初使用名称bar声明的整数。 从概念上讲,它不是一个单独的,有诗意的东西,语言规则,类型和值类别证明了这一点。

当然,foo()返回引用这一事实并不只是被忽略:这就是为什么不进行复制,以及为什么结果表达式的值类别为lvalue而不是rvalue。

因此,引用类型并不支持语言使用不同表达式在多个位置引用对象的能力:它们只给C++程序员提供了访问该能力的权限。

(不过,这里有时可能会出现“抽象泄漏”;例如,使用引用类型声明的类成员几乎必须占用存储空间,并且在我所知道的每个ABI中都将作为指针实现。这只是一种实际需要。)

我指的是编译器创建的实际计算机程序。 它包含目标计算机将执行的实际指令。

在这个真实的程序中,对于任何访问,可能有也可能没有一个指针的取消引用,甚至可能有也可能没有一个对象存储在内存中的某个地方。 相反,该值可能只是被烘焙到您的代码中。 有些人称之为“优化”,但实际上,它只是你的编译器产生了最好的计算机程序,具有你所描述的语义。

这不仅适用于引用,也适用于非引用。 例如,在任何适当的“优化”级别,您的整个实际程序可能只是将整数20发送到std::cout机器的代码; 在执行过程中,这些int没有理由作为对象实际“存在”于任何内存位置。

因此,如果您真的关心性能,您需要阅读汇编代码来了解实际发生的情况。 否则,你不可能也不需要预测。

…没有真正的理由担心你的引用本身是别名还是“变量”,因为编译过程已经完全模糊了两者之间的区别。

相关问题


MySQL Query : SELECT * FROM v9_ask_question WHERE 1=1 AND question regexp '(c++11|变量|引|用为|lvalues|真的|var|别名)' ORDER BY qid DESC LIMIT 20
MySQL Error : Got error 'repetition-operator operand invalid' from regexp
MySQL Errno : 1139
Message : Got error 'repetition-operator operand invalid' from regexp
Need Help?