多个"常量引用"变量可以共享同一个内存吗?

Can multiple 'const reference' variables share the same memory?

本文关键字:同一个 内存 共享 常量 引用 变量 多个      更新时间:2023-10-16

我想知道在同一范围内将多个"常量引用"变量指向同一对象是否有内存成本:

const Animal& animal = getAnimal();
const Dog& dog = static_cast<const Dog&>(animal);

从概念上讲,animaldog是两个变量,每个变量的指针大小,因此将占用 2 个寄存器(或堆栈上的 2* 指针大小区域(。

但是(假设没有多重继承等(,编译器可以知道它们都必须在其生命周期中保持相同的指针值。

那么,这两个变量可以共享单个寄存器(或堆栈上的单个指针大小的区域(吗?
通过"can",我的意思是:

  • C++标准允许吗?
  • 现代编译器会这样做吗?

C++标准允许吗?

当然,为什么不呢。你无法分辨出其中的区别。所谓的"as-if 规则"允许编译器进行任何优化,只要可观察行为与未进行任何优化的行为相同(旁注:也有例外,允许优化更改可观察行为(。

从概念上讲,动物和狗是两个变量,每个变量的指针大小,...

不。从概念上讲,引用是别名。它们不需要占用任何空间,因为它们只是实际对象的不同名称。C++标准没有指定引用的大小或实现方式。sizeof引用会为您提供引用对象的大小。引用的地址是引用对象的地址。我不知道有任何方法可以区分引用是作为指针还是以任何其他方式实现(我强烈怀疑是否有可移植的方式(。

现代编译器会这样做吗?

为了回答这个问题,我建议你拿一些真实的代码并查看编译器的输出。这是一个很好的工具来帮助解决这个问题:https://godbolt.org/。

PS:我感觉到一个小误会。实际上,示例中的const并不那么相关。具有const引用并不意味着该值不会更改。这仅意味着不允许通过该引用更改值。也许最好用一个小例子来解释:

struct foo {
const int& ref;
};
int main() {
int x = 1;
foo f{x};
x = 42;
}    

在这里,fconst引用了x。这并不意味着x永远不会被修改。这仅意味着f无法通过ref修改x。这在多线程环境中尤其重要,因为仅仅因为您有一个const引用就假定对象const会导致麻烦。

多个"常量引用"变量可以共享相同的内存吗?

当然,变量有时可以共享内存。在某些情况下,这两个变量都可能使用任何内存。

这适用于所有普通类型。

从概念上讲,动物和狗是两个变量,每个变量的指针大小

从概念上讲,该标准没有指定引用的大小。但实际上,如果引用变量需要存储,那么它确实是指针的大小。

C++标准允许吗?

是的。

现代编译器会这样做吗?

取决于上下文。有些情况下他们会这样做,有些情况下他们实际上不能。