7

为什么右值没有内存地址?它们是在程序执行时没有加载到 RAM 中还是引用存储在处理器寄存器中的值?

4

5 回答 5

10

您的问题(“为什么右值没有内存地址?”)有点困惑。右值是一种表达式。 表达式没有地址: 对象有地址。问“为什么不能将地址运算符应用于右值表达式?”会更正确。

答案相当简单:您只能获取对象的地址,并非所有右值表达式都引用对象(例如,表达式42有值但不引用对象)。

一些右值表达式确实引用了对象,但这些对象缺乏持久性。右值表达式引用的对象是一个临时对象,并在创建它的表达式的末尾被销毁。这样的对象确实有地址(您可以通过在临时对象上调用成员函数很容易地发现这一点;this指针必须指向临时对象,因此临时对象必须有地址)。

这是左值表达式和右值表达式之间的根本区别。左值表达式指的是具有持久性的对象:左值表达式所指的对象在单个表达式之外仍然存在

于 2011-09-10T06:59:02.980 回答
1

rvalue其视为表达式。该本身没有地址。但是表达式中涉及的对象确实有地址。您可以获取对象的地址,甚至可以是临时对象。

考虑到这一点,

const int & i = 10; //ok

这里,是一个10右值,所以它看起来是. 不,那是错误的。是类型的临时对象的地址,它是根据表达式创建的。而且由于临时对象不能绑定到非常量引用,所以我使用. 这意味着,以下是一个错误:&i10&iint10const

int & i = 10; //error
于 2011-09-10T06:53:13.927 回答
1

这个问题混合了与“规范”和“实施”相关的两个不同方面。

“规范”定义了一些抽象规则,这些规则定义了语言相对于它所使用的抽象机器的行为方式。使“抽象机器”适应其下的“真实机器”,这是编译器(而不是语言)的目的。

规范强制执行的是-从语言的角度来看-“存储”(具有正确地址的一块内存)仅提供给具有名称的对象(用于名称存在的范围的存在)或通过显式请求 ( new) 动态分配。其他一切都是“临时的”:像对象一样分配、复制和移动,但不需要存在于定义明确且稳定的位置。至少,不是为了语言的目的。

当然,它必须(物理上)保留在某个地方,因此您可以通过适当的强制转换或转换来尝试猜测内存地址。但是,如果您尝试积极使用语言规范,则不会授予任何一致的行为。这意味着不同的编译器可以表现出不同的行为,并且可以更好地优化它们以更好地尊重它们所针对的真实机器。

于 2011-09-10T07:17:53.340 回答
-1

你是什​​么意思,右值确实有一个地址。曾经尝试过

Type const value& = rvalue;
Type const* address = &value;
于 2011-09-10T06:52:46.803 回答
-2

简单拿下这个案例

int a = 1 + 2;

1+2 被解析为 3。

问你自己:

  • 3是一个对象吗?
  • 3 将位于内存中的哪个位置?

当你需要一个对象的地址时,你使用 &。

如果右值是可寻址的,这意味着您可以声明一个指针,指向您的计算机决定存储的位置 3

int* a = &3;

这看起来对吗?:)

于 2011-09-10T07:04:22.757 回答