【问题标题】:Does a reference have a storage location?参考是否有存储位置?
【发布时间】:2018-03-25 05:01:14
【问题描述】:

引用有存储位置还是只是另一个位置的别名?这是否因 C++ 版本而异,还是与所有 C++ 版本一致?如果一个引用有一个存储位置,那么它是否只允许像类型这样的指针上的值语义?

当你这样使用参考文献时,它是如何工作的:

struct aStruct{
   int aVariable;
   aClass& aReferencetoaClass;
};

是占用空间还是别名?

【问题讨论】:

    标签: c++ reference language-lawyer memory-layout storage-duration


    【解决方案1】:

    latest C++20 spec(§ 9.2.3.3) 并且至少从C++ 2005 draft spec 状态开始:

    未指定引用是否需要存储

    实际实施是根据具体情况而定的。显然,如果一个类有一个成员变量,它是一个需要存储在某处的引用。但是正如您所说,编译器在何时将引用单独用作别名时有回旋余地。

    【讨论】:

    • 嗯,是的 - 这取决于上下文。在结构中,您必须让引用需要存储,否则您将如何管理不同的结构实例?在您创建临时引用的代码块中,它可能只是一个别名。我认为不指定它的目的正是让编译器能够选择。
    • 如果一个对象在 ABI 边界可用,它需要遵循 ABI。
    【解决方案2】:

    大多数编译器,至少对于 C++17 之前的任何 C++ 标准,都会有效地将引用实现为指针,除非进行优化。

    特别是在struct 中,它将占用指针的大小(加上对齐/填充等)。

    因此,这将适用于大多数环境:

    struct S {
        char & a;
    };
    
    static_assert(sizeof(S) == sizeof(void *));
    

    【讨论】:

    • "特别是在结构内部" - 不同意,它可能引用同一个结构的另一个成员,那么它可能只是一个别名。
    • @Slava 怎么样?所有数据成员都需要有一个唯一的地址(直到我们在 C++20 中得到 [[no_unique_address]])。
    • @Acorn 未指定引用是否具有存储空间,因此未指定它们是否具有地址。
    • @eerorika 确实如此。我想有人可以提出一个极端情况,可以证明一个类型有一个引用成员,它总是指向一个已知的地方,所以它可以优化它——但我怀疑编译器是否会为此优化,给定在实际代码中基本没用。
    • @Slava:是的,理论上 C++ 实现可以做到这一点。在实践中,我不知道有任何优化可以证明始终初始化为引用已知位置(结构/类的另一个成员,或始终指向同一个静态对象)的引用。所以在实践中,引用基本上是char *const c; 周围的语法糖。否则,结构布局将取决于有关如何初始化引用的编译时证明。这可能取决于您是否使用优化进行编译,并且无法链接发布+调试对象=奇怪。
    猜你喜欢
    • 2017-05-04
    • 2017-07-17
    • 2016-05-02
    • 1970-01-01
    • 2021-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多