【问题标题】:Why do references take up memory?为什么引用会占用内存?
【发布时间】:2020-12-22 15:51:43
【问题描述】:

看起来,引用只是一个别名,但是,例如,将引用字段添加到struct 会增加结构的大小,即使引用在声明时被初始化为相同结构的另一个字段的别名。

例如:


#include <iostream>

using namespace std;

int
main(int, char **)
{
    struct {
        int integers[2];
    } first;
    struct {
        int integers[2];
        int &one = integers[0];
        int &two = integers[1];
    } second;

    cout << sizeof first << " " << sizeof first.integers << " " <<
        sizeof second << " " << endl;

    return 0;
};

上面的程序在此处打印:8 8 24。我理解的前两个数字,第三个 - 不。为什么添加此类引用很重要——存储在该内存中的内容在编译时时无法解析?与指针不同,一旦声明,引用无论如何都不能通过设计更改,可以吗?那么为什么要存储它们呢?

【问题讨论】:

  • 虽然它可能可以在编译时解决,但看起来编译器还没有使用这种优化进行编程。通常,引用数据成员将像T * const 成员一样实现。
  • 请考虑引用数据成员并不总是那么容易弄清楚。考虑一下如果添加一个将其他对象分配给这些引用的构造函数会发生什么。编译器需要能够在消除这些成员之前确定这是否可能发生。
  • 我预计这要么是一个硬优化,要么是在实际代码中不会经常发生的情况,因此值得。但是,clang 和 gcc 都是开源的,并且都乐于接受一个补丁来优化这个用例场景。
  • @MikhailT。我以为你的问题很笼统。无论如何,如果您手动初始化成员引用怎么办?简化演示:godbolt.org/z/3MxjKe。我不认为同一类型的对象的字节大小可以取决于它们的初始化形式。
  • @MikhailT。在我的示例中,x.r 不指向x.a,它指向a 局部变量main。因此,x 内部的 ar 不是一回事。我可能应该为该局部变量使用不同的名称:godbolt.org/z/1n3jaE

标签: c++ reference sizeof


【解决方案1】:

即使 firstsecond 结构按照您的方式定义,我认为,这些引用成员也不能被优化掉(如果我们不是在谈论您编写的特定程序,而是在一般情况下使用这些结构)。例如,假设在代码中的某个时刻,您决定创建second 结构的实例,但以不同的方式初始化引用成员,甚至可能以一种在编译时未知的动态方式进行初始化。考虑以下用法:

#include <iostream>

int main()
{
    struct
    {
        int integers[2];
    } first;

    struct
    {
        int integers[2];
        int &one = integers[0];
        int &two = integers[1];
    } second;

    int user_choice{ 0 };
    std::cin >> user_choice;

    int i{ 56 }, j{ 78 };
    decltype(second) third{ {12, 34}, i, (user_choice < 42) ? i : j };

    std::cout << third.integers[0] << ' ' << third.integers[1] << ' '
        << third.one << ' ' << third.two << '\n';
}

在上面的程序中,编译器根本无法事先知道third.two 将引用i 还是j:这取决于用户在运行时输入的数字(试试https://godbolt.org/z/43bM1o例如,输入7 而不是100)。

【讨论】:

    【解决方案2】:

    这个答案提到对象很可能会被优化掉,但调用sizeof 可以强制它们不被优化,因为删除它们将是结构大小的“可观察”变化:

    https://stackoverflow.com/a/55060982

    【讨论】:

    • C++ 的量子力学...不过说真的,这部分可观察到有什么问题?无论如何,引用不应该——不应该——有自己的大小(也不是地址)......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-10
    • 1970-01-01
    • 1970-01-01
    • 2019-01-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多