【问题标题】:C++ lvalue referencesC++ 左值引用
【发布时间】:2020-05-17 15:33:25
【问题描述】:

所以最近我重新访问了类型声明的引用,但我不太了解它们。

考虑一下这个伪代码:

int ia = 10;
int& ref = ia;

现在,我的问题是:

  1. 这些int& ref如何在内部工作,这是否意味着ref的地址被分配了ia的地址,因此等于&ia如果不是那么编译器在看到这些引用时会做什么?
  2. 为什么这些引用不在 c++ 程序中编译?

【问题讨论】:

    标签: c++ reference lvalue


    【解决方案1】:

    您根本不必考虑地址。 ref 只是 ia 的另一个名称,或者换句话说,refia 的别名。只是代码的语法糖。

    这种情况下的编译器根本不需要做太多,只要跟踪代码何时包含ref,将其替换为ia即可。

    【讨论】:

    • 感谢您的回复,但我想知道这是如何在内部工作的。编译器看到这个会做什么?
    • @Alex • C++ 标准没有规定编译器在内部做什么。我的编译器尽可能消除引用,并将其视为只是对所引用对象的别名替换。
    • @Alex,一般来说,您会尽可能避免使用宏。
    • @Alex,处理器使用宏的定义对您的源代码执行搜索替换,然后编译最终结果(编译步骤中没有宏)。所以如果你有#define MY_CONSTANT 2int a = MY_CONSTANT; 这样的东西,那么对于编译器来说它就是int a = 2;。这是一个您不想使用宏的示例,因为 constconstexpr 更适合这样的用例。现在正确使用宏仅限于少数情况,您经常可以看到它们用于创建单元测试。
    • @Alex 您通常将它们用于更复杂的表达式或作为函数参数。
    【解决方案2】:

    C++ 标准没有指定编译器应该如何实现引用。很多人认为它们只是别名,但实际上,它们只是实现为 const 指针。

    C++ 引用实际上是 const 指针。所以:

    int ia = 10;
    int& ref = ia;
    ref++; // ia is 11 now
    

    可能会被编译器转换为:

    int ia = 10;
    int* const ref = ia;
    (*ref)++; // ia is 11 now
    

    它们需要初始化,因为必须初始化常量。

    【讨论】:

    • 在大多数情况下这是错误的,例如参见godbolt.org/z/TA8tkN
    • 这不是假的。尝试使用 -00。并松开iostream 以获得更清晰的输出。另见:godbolt.org/z/xEQVXe,请查看此线程:twitter.com/tvaneerd/status/1252653227885178882?s=20
    • 如果你松开了ostream,代码就是一个noop,O0在这里更像是AST的反映,而不是引用的语义。
    • O0 是编译器在调试模式下生成的实际程序集。在不同的情况下,编译器可能无法将其优化为简单的赋值。
    猜你喜欢
    • 2011-05-07
    • 2011-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多