代码之家  ›  专栏  ›  技术社区  ›  rekli

反汇编中的引用类型和指针

  •  3
  • rekli  · 技术社区  · 16 年前

    为什么在编译代码中引用类型和指针是相同的?(你可以在第三行和第四行看到)。我试图弄明白,但显然我做不到。

    如果引用类型变量必须在声明时初始化并且不能更改,那么是否需要像指针中那样执行间接寻址?

    int x = 10;
    

    MOV双字指针[X],0ah

    int y = x;
    

    MOV EAX,双字指针[X]

    MOV双字指针[Y],EAX

    int &i = y;
    

    Lea EAX[是]

    MOV双字指针[I],EAX

    int *p = &x;
    

    LEA EAX[x]

    MOV双字指针[P],EAX

    p = &i;
    

    MOV EAX,双字指针[I]

    MOV双字指针[P],EAX

    x = i;
    

    MOV EAX,双字指针[I]

    MOV ECX,双字指针[EAX]

    MOV双字指针[X],ECX

    5 回复  |  直到 16 年前
        1
  •  2
  •   Michael Burr    16 年前

    如果编译器知道referece总是引用一个特定的对象/项,那么编译器当然可以优化间接寻址。

    然而,大多数引用实际上是在运行时绑定的。即使引用的某个特定实例无法恢复,对某个特定作用域的不同执行或包含引用成员的对象的不同实例也可能运行,并且这些实例的引用绑定到不同的对象。使用间接寻址是编译器处理这一问题的方便方法。

    引用仅绑定到单个对象的情况可能相对较少,以至于编译器可能找不到优化——特别是在大多数情况下,优化可能不是一个显著的收益。

    此外,我怀疑您没有启用编译器优化-使用代码并使用 y i 在VC++2005中对它们的地址进行了一次快速的优化测试,结果表明编译器没有实现 作为指针,但作为 Y (即,任何时候经过 &i ,编译器使用 Y 直接)。

    如果您正在查看编译器的调试输出,那么它总是将引用视为幕后的指针,这并不奇怪。

        2
  •  2
  •   Khaled Alshaya    16 年前

    引用只是受限制的指针。唯一的区别是它们必须指向现有的变量。你可以在C++中绕过这个问题,但是很难错过:

    int& r = *(reinterpret_cast<int*>(0x0));
    

    当然,这是未定义的行为!

    所以,基本上是 实施 作为指针。它们在许多地方的用法不同,例如,当引用作为r值或l值时,会自动取消引用:

    int x = 0;
    
    int& r = x; // 1) no need to take the address of x like &x
    
    r = r * x; // Manually: (*r) = (*r) * x
    

    它们为原始指针提供了一种更安全的替代方法。而且,它们的语法要比原始指针优雅得多。假设在重载类运算符时没有引用。

    总之,它们是受限制的指针,具有更好/更安全的别名,但功能性降低。

        3
  •  1
  •   rlbond    16 年前

    引用在内部表示为指针。它是 编译程序 这就限制了初始化和不可再密封性。

    如果引用类型变量必须为 在声明中初始化,不能 有什么需要改变的吗 像指针一样间接?

    唯一的选择是复制值,这不是引用所做的。引用的作用类似于指针:它保存在对象的位置上。区别在于引用的行为与对象本身类似,而不需要显式地取消引用。

        4
  •  1
  •   seaotternerd    11 年前

    C++ FAQ Lite为你所看到的提供了一个很好的解释: https://isocpp.org/wiki/faq/references

    本质上,简而言之,编译器本质上把它当作一个指针,它使用对象的地址,并为您进行解引用工作。

        5
  •  0
  •   Gautham Ganapathy    16 年前

    是的,引用只是指针的语法糖分(有适合新语法的限制)。它还允许C++通过引用参数传递副本,而与只有值拷贝(甚至指针参数)的C相反。