多个“const 引用”变量可以共享相同的内存吗?

sml*_*mls 2 c++ memory reference compiler-optimization

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

const Animal& animal = getAnimal();
const Dog& dog = static_cast<const Dog&>(animal);
Run Code Online (Sandbox Code Playgroud)

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

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

那么,这两个变量能否共享一个寄存器(或堆栈上一个指针大小的区域)?
“可以”,我的意思是:

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

for*_*818 5

C++ 标准允许吗?

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

从概念上讲,animal 和 dog 是两个变量,每个变量都是指针大小,...

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

现代编译器会这样做吗?

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

PS:感觉有点小误会。事实上,const在你的例子中并不是那么相关。拥有const引用并不意味着该值不会改变。这仅意味着您不能通过该引用更改值。也许最好用一个小例子来解释:

struct foo {
    const int& ref;
};

int main() {
    int x = 1;
    foo f{x};
    x = 42;
}    
Run Code Online (Sandbox Code Playgroud)

这里f持有constx. 这并不意味着x永远不会被修改。它只是意味着f不能修改x通过ref。这在多线程环境中尤其重要,在这种环境中,假设对象const只是因为您有const引用会导致麻烦。