多个 'const reference' 变量可以共享同一个内存吗?
Can multiple 'const reference' variables share the same memory?
我想知道在同一范围内指向同一对象的多个“常量引用”变量是否会产生内存成本:
const Animal& animal = getAnimal();
const Dog& dog = static_cast<const Dog&>(animal);
从概念上讲,animal
和 dog
是两个变量,每个都是指针大小,因此会占用 2 个寄存器(或堆栈上的 2* 指针大小的区域)。
但是(假设没有多重继承等),编译器可以知道它们在整个生命周期中都必须持有相同的指针值。
那么,这两个变量可以共享一个寄存器(或堆栈上的一个指针大小的区域)吗?
“可以”是指:
- C++ 标准允许吗?
- 现代编译器会这样做吗?
Does the C++ standard allow it?
当然可以,为什么不呢。你无法分辨出区别。所谓的“as-if rule”允许编译器进行任何优化,只要可观察到的行为与未进行任何优化一样(旁注:有例外,允许优化改变可观察到的行为) .
Conceptually, animal and dog are two variables, each of pointer size, ...
没有。从概念上讲,引用是别名。它们不需要任何 space,因为它们只是实际对象的不同名称。 C++ 标准没有指定引用的大小或它是如何实现的。 sizeof
引用为您提供所引用对象的大小。引用的地址是被引用对象的地址。我不知道有什么方法可以区分引用是作为指针还是以任何其他方式实现的(而且我强烈怀疑是否存在可移植的方式)。
Would modern compilers do it?
为了回答这个问题,我建议您使用一些实际代码并查看编译器输出。这是一个很好的工具来帮助解决这个问题:https://godbolt.org/.
PS: 感觉有点小误会。实际上,您示例中的 const
并不相关。拥有 const
引用并不意味着该值不会改变。这仅意味着您不允许通过该引用更改值。也许最好用一个小例子来解释:
struct foo {
const int& ref;
};
int main() {
int x = 1;
foo f{x};
x = 42;
}
此处 f
持有对 x
的 const
引用。这并不意味着 x
永远不会被修改。这仅意味着 f
无法通过 ref
修改 x
。这在多线程环境中尤其重要,假设一个对象是 const
仅仅因为你有一个 const
引用会导致麻烦。
Can multiple 'const reference' variables share the same memory?
当然,变量有时可以共享内存。在某些情况下,两个变量都可能不使用任何内存。
这适用于所有普通类型。
Conceptually, animal and dog are two variables, each of pointer size
概念上,标准没有指定引用的大小。但实际上,如果引用变量需要存储,那么它确实是指针的大小。
Does the C++ standard allow it?
是的。
Would modern compilers do it?
取决于上下文。有些情况下他们会,有些情况下他们实际上不能。
我想知道在同一范围内指向同一对象的多个“常量引用”变量是否会产生内存成本:
const Animal& animal = getAnimal();
const Dog& dog = static_cast<const Dog&>(animal);
从概念上讲,animal
和 dog
是两个变量,每个都是指针大小,因此会占用 2 个寄存器(或堆栈上的 2* 指针大小的区域)。
但是(假设没有多重继承等),编译器可以知道它们在整个生命周期中都必须持有相同的指针值。
那么,这两个变量可以共享一个寄存器(或堆栈上的一个指针大小的区域)吗?
“可以”是指:
- C++ 标准允许吗?
- 现代编译器会这样做吗?
Does the C++ standard allow it?
当然可以,为什么不呢。你无法分辨出区别。所谓的“as-if rule”允许编译器进行任何优化,只要可观察到的行为与未进行任何优化一样(旁注:有例外,允许优化改变可观察到的行为) .
Conceptually, animal and dog are two variables, each of pointer size, ...
没有。从概念上讲,引用是别名。它们不需要任何 space,因为它们只是实际对象的不同名称。 C++ 标准没有指定引用的大小或它是如何实现的。 sizeof
引用为您提供所引用对象的大小。引用的地址是被引用对象的地址。我不知道有什么方法可以区分引用是作为指针还是以任何其他方式实现的(而且我强烈怀疑是否存在可移植的方式)。
Would modern compilers do it?
为了回答这个问题,我建议您使用一些实际代码并查看编译器输出。这是一个很好的工具来帮助解决这个问题:https://godbolt.org/.
PS: 感觉有点小误会。实际上,您示例中的 const
并不相关。拥有 const
引用并不意味着该值不会改变。这仅意味着您不允许通过该引用更改值。也许最好用一个小例子来解释:
struct foo {
const int& ref;
};
int main() {
int x = 1;
foo f{x};
x = 42;
}
此处 f
持有对 x
的 const
引用。这并不意味着 x
永远不会被修改。这仅意味着 f
无法通过 ref
修改 x
。这在多线程环境中尤其重要,假设一个对象是 const
仅仅因为你有一个 const
引用会导致麻烦。
Can multiple 'const reference' variables share the same memory?
当然,变量有时可以共享内存。在某些情况下,两个变量都可能不使用任何内存。
这适用于所有普通类型。
Conceptually, animal and dog are two variables, each of pointer size
概念上,标准没有指定引用的大小。但实际上,如果引用变量需要存储,那么它确实是指针的大小。
Does the C++ standard allow it?
是的。
Would modern compilers do it?
取决于上下文。有些情况下他们会,有些情况下他们实际上不能。