为什么右值没有地址?
Why don't rvalues have an address?
为什么右值没有内存地址?当程序执行时,它们是否没有加载到RAM中,或者它是否引用存储在处理器寄存器中的值?
你的问题("为什么右值没有内存地址?")有点困惑。右值是一种表达式。表达式没有地址:对象有地址。更正确的问题是"为什么不能将地址操作符应用于右值表达式?"
这个问题的答案很简单:你只能取一个对象的地址,并不是所有的右值表达式都指向对象(例如,表达式42
有一个值,但不指向对象)。
一些右值表达式确实引用对象,但这些对象缺乏持久性。右值表达式引用的对象是一个临时对象,在创建该对象的表达式结束时销毁。这样的对象确实有地址(你可以很容易地通过调用临时对象的成员函数发现这一点;this
指针必须指向临时对象,因此临时对象必须有地址)。
这是左值表达式和右值表达式的根本区别。
将rvalue
视为表达式的值。值本身没有地址。但是表达式中涉及的对象确实有地址。可以取对象的地址,即使它是临时对象。
考虑这个,
const int & i = 10; //ok
这里,10
是一个右值,因此显示 &i
是10
的地址。不,这是错误的。&i
是int
类型的临时对象的地址,该对象是由表达式10
创建的。由于临时对象不能绑定到非const引用,所以我使用const
。这意味着,下面是一个错误:
int & i = 10; //error
这个问题混合了与"规范"answers"实现"相关的两个不同方面。
"规范"定义了一些抽象规则,这些规则定义了语言相对于它所使用的抽象机器的行为方式。使"抽象机器"适应于其下的"真实机器"是编译器(而不是语言)的目的。
规范强制执行的是-从语言的角度来看-"存储"(具有适当地址的内存块)仅给予具有名称的对象(对于名称存在的作用域)或通过显式请求(new
)动态分配的对象。其他一切都是"临时的":像对象一样赋值、复制和移动,但不需要存在在定义良好且稳定的位置。至少,不是为了语言的目的。
当然,它必须(物理地)留在某个地方,因此您可以-通过适当的强制转换或转换-尝试猜测内存地址。但是,如果您尝试积极使用它,语言规范不会授予任何一致的行为。这意味着不同的编译器可以表现出不同的行为,并根据它们所针对的实际机器进行更好的优化。
什么意思,右值确实有地址。试过
Type const value& = rvalue;
Type const* address = &value;
就拿这个例子来说
int a = 1 + 2;
1+2被解析为3。
问问自己:
- 3是对象吗?
- 3在内存中的位置?
当你需要一个对象的地址时,使用&
如果右值是可寻址的,这意味着你可以声明一个指针,指向你的计算机决定存储3
int* a = &3;
看起来对吗?:)
- 向量元素的引用地址与它所指向的向量元素的地址不同.为什么
- 为什么我在leetcode上收到AddressSanitizer:地址0x602000000058上的堆缓冲区溢出错误
- 为什么指针不写入类的地址?
- 为什么 ulimit -v 在 Clang 的地址清理器下不起作用?
- 为什么 vector 的随机访问迭代器给出与指针不同的内存地址?
- 为什么未命名的结构内联变量在每个翻译单元中没有相同的地址?
- 为什么我可以将变量存储在不是其最小对齐方式的倍数的地址?
- 为什么C++总是显示十六进制内存地址,而不仅仅是整数?
- 为什么两个矢量元素的地址有这么大的差距?
- 如果 const 不分配内存,为什么我可以获取 const 的地址?
- 为什么同一个变量的内存地址不同?
- 为什么成员函数地址离自由函数这么远?
- 为什么我得到以下代码地址清理器:未知地址错误的SEGV
- 堆栈分配的类类型.为什么两个 ID 实例的地址相同?
- 为什么每次执行时函数的地址都不同?
- 为什么地址相同?
- 为什么存储在数组中的地址值与其自己的地址相同,它应该指向某个不同的地址(&arr[0])?
- 为什么 C++ 地址中的矢量无法通过原始指针访问
- 为什么下面的代码段返回指针指向的值而不是指针的地址?
- 为什么使用存储在虚拟方法表中的地址调用虚拟函数的函数会返回垃圾?