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

时间:2021-05-27 12:32:12

标签: c++ reference

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

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

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;
}

2 个答案:

答案 0 :(得分:3)

迂腐的答案是:无论编译器感觉如何,重要的是它按照语言语义的规定工作。

要获得实际答案,您必须查看结果程序集,或者大量使用未定义行为。在这一点上,它变成了一个特定于编译器的问题,而不是一个“一般的 C++”问题

在实践中,需要存储的引用本质上变成了指针,而局部引用往往会被编译为不存在。后者通常是这种情况,因为保证引用永远不会被重新分配意味着如果你能看到它被分配,那么你就完全知道它所指的是什么。但是,您不应该为了正确性而依赖它。

为了完整性

通过将包含引用的结构的内容存入 char 缓冲区,可以从有效代码中一些深入了解编译器正在做什么:

#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 ;
}

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

答案 1 :(得分:2)

它在很大程度上依赖于编译器,也许编译器决定优化代码,因此它会使它有价值或...,但据我所知,引用将编译器像指针一样,我的意思是,如果您看到它们的结果程序集,它们会像指针一样被编译。