为什么引用会占用内存?

3
似乎引用只是一个别名,但是,在向一个结构体(例如)添加引用字段时,即使该引用在声明时作为另一个同一结构体字段的别名进行初始化,结构体的大小也会增加。
例如:

#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”的成员。 - François Andrieux
考虑到已经实现了一些其他(非常惊人的)优化,这个似乎相当简单... 然而,即使是clang-10也没有它... - Mikhail T.
1
我认为这可能是一个艰难的优化,或者在实际代码中并不经常发生,因此不值得去优化。然而,无论是clang还是gcc都是开源的,它们都很乐意接受一个补丁来优化这种使用情况。 - Eljay
1
@MikhailT。我认为你的问题是通用的。无论如何,如果您手动初始化成员引用会怎样呢?简化演示:https://godbolt.org/z/3MxjKe。我不认为相同类型的对象的字节大小可以取决于它们的初始化形式。 - Daniel Langr
1
@MikhailT。在我的例子中,x.r并不指向x.a,而是指向main函数内的局部变量a。因此,x内的ar并不是同一个东西。我可能应该为那个局部变量使用不同的名称:https://godbolt.org/z/1n3jaE。 - Daniel Langr
显示剩余8条评论
2个回答

2

1
C++的量子力学... 说真的,这个部分被观察有什么问题吗?引用本来就不应该有自己的大小(也没有地址)... - Mikhail T.

2
即使您以您所定义的方式定义了第一和第二个结构,我认为,在使用这些结构的一般情况下,那些引用成员也无法被优化掉(如果我们不是在谈论您编写的特定程序)。例如,假设在代码的某个点上,您决定创建第二个结构的实例,但要以不同的方式初始化引用成员,甚至以动态方式进行初始化,而在编译时未知。请考虑以下用法:
#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)。请注意保留HTML标记。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接