编译C++引用后会发生什么?

编译C++引用后会发生什么?,c++,reference,C++,Reference,编译后,引用变成了什么,地址还是常量指针 我知道指针和引用之间的区别,但我想知道底层实现之间的区别 int main() { int a = 1; int &b = a; int *ptr = &a; cout << b << " " << *ptr << endl; // 1 1 cout << "&b: " << &

编译后,引用变成了什么,地址还是常量指针

我知道指针和引用之间的区别,但我想知道底层实现之间的区别

int main()
{
    int a = 1;
    int &b = a;
    int *ptr = &a;
    cout << b << " " << *ptr << endl;  // 1 1
    cout << "&b: " << &b << endl;      // 0x61fe0c
    cout << "ptr: " << ptr << endl;    // 0x61fe0c
    return 0;
}

学究式的回答是:不管编译器感觉如何,重要的是它按照语言语义指定的方式工作

要得到实际的答案,您必须查看生成的程序集,或者大量使用未定义的行为。这时,它变成了编译器特有的问题,而不是一般问题< /P>中的C++。 实际上,需要存储的引用基本上变成了指针,而本地引用往往会被编译而不存在。后者通常是这样的,因为保证引用永远不会被重新分配意味着如果你能看到它被分配,那么你就完全知道它指的是什么。但是,您不应该为了正确性的目的而依赖于此

为了完整起见

通过将包含引用的结构的内容memcping到char缓冲区中,可以了解编译器在有效代码中执行的操作:


当我在我的编译器上运行它时,我得到了存储在结构中的val的endian翻转地址。

学究式的答案是:无论编译器感觉如何,重要的是它按照语言语义的指定工作

要得到实际的答案,您必须查看生成的程序集,或者大量使用未定义的行为。这时,它变成了编译器特有的问题,而不是一般问题< /P>中的C++。 实际上,需要存储的引用基本上变成了指针,而本地引用往往会被编译而不存在。后者通常是这样的,因为保证引用永远不会被重新分配意味着如果你能看到它被分配,那么你就完全知道它指的是什么。但是,您不应该为了正确性的目的而依赖于此

为了完整起见

通过将包含引用的结构的内容memcping到char缓冲区中,可以了解编译器在有效代码中执行的操作:



当我在我的编译器上运行这个时,我得到了存储在结构中的val的endian翻转地址。

它严重依赖于编译器,可能编译器决定优化代码,因此它会使它有价值,或者。。。,但据我所知,引用会像指针一样被编译器编译,我的意思是,如果你看到它们的结果汇编,它们会像指针一样被编译。

这在很大程度上取决于编译器,也许编译器决定优化代码,因此它会使它有价值,或者。。。,但是,我知道引用会像指针i一样编译,如果你看到他们的结果汇编,它们就像指针一样编译。

程序集输出给你什么建议?注意,引用不是C++标准中的对象,例如,相同的变量值,可以通过指针或引用找到相同的地址,没什么特别的。@BarryBao这是引用点,一旦指定,它们就可以与引用的对象区分开来。在您的示例中,&b和&a是同一件事。绝对不可能得到引用的地址。这是一个人的昵称和一个人的名字之间的关系。程序集输出给你什么?注意,引用不是C++标准中的一个对象,例如,相同的变量值,可以通过指针或引用找到相同的地址,没有什么特别的。@ BarryBao,这是引用的要点。一旦指定,它们将无法与它们引用的对象区分开来。在您的示例中,&b和&a是同一件事。绝对不可能得到引用的地址。这是一个人的昵称和名字之间的关系。是的,我只是想知道更多。你说得很对。谢谢你的回答。@BarryBao我已经添加了更多的细节。是的,我只是想了解更多。你说得很对。谢谢你的回答。@BarryBao我已经添加了更多的细节。是的,最后是地址。谢谢你的回答。我不想死。是的,这是最后的地址。谢谢你的回答。我不想死。
#include <iostream>
#include <array>
#include <cstring>

struct X {
    int& ref;
};

int main() {
  constexpr std::size_t x_size = sizeof(X);

  int val = 12;
  X val_ref = {val};

  std::array<unsigned char, x_size> raw ;
  std::memcpy(&raw, &val_ref, x_size);

  std::cout << &val << std::endl;

  std::cout << "0x";
  for(const unsigned char c : raw) {
      std::cout << std::hex << (int)c;
  }
  std::cout << std::endl ;
}