我想知道如果我调用函数f(3),编译器如何保存这个临时int;
int f (int x) { return x; }
Run Code Online (Sandbox Code Playgroud)
以及编译器将如何解决这个问题:
int a=f(3);
Run Code Online (Sandbox Code Playgroud)
就像做一个int a = x; (我知道x已经被破坏了)或者它确实创建了一个名为f(3)的临时变量,就像这样int f(3)=x;
int& a=f(3);
Run Code Online (Sandbox Code Playgroud)
为什么这不起作用?
编译器将执行以下操作之一:
int a = 3.引用变量,int &a在代码中声明的引用变量是"现有内存位置的不同名称".因此声明int &a不会为int任何地方分配空间.它只是声明a引用已分配的内存位置.
此位置可能是现有变量int b,因此您可以说:
int b;
int &a = b;
Run Code Online (Sandbox Code Playgroud)
这里,a将参考相同的内容b."现有对象的新名称"是一个很好的习惯用法.
你可能会想到并说int &a = array[5],所以它a指的是int数组的第6个元素array,或者int &a = *(int*)0x12345678指的是特定的内存位置,但是我很离题.
你的代码
int &a = 3;
Run Code Online (Sandbox Code Playgroud)
无法工作,因为它3是一个临时对象,在执行语句后会被遗忘.要理解这个问题,要从根本上考虑这个问题:如果a引用已经分配的内存位置,在int &a = 3执行语句之后它将引用什么,并且不再有临时对象3?
这也是函数中引用变量的常见问题:返回对函数本地对象的引用是未定义的行为......但我再次离题了.你总是必须有一个"活的,分配的对象" a来引用,故事的结尾.
对于像这样的陈述通常会发生什么
int a = 3;
Run Code Online (Sandbox Code Playgroud)
是编译器生成代码(简化):
重点是:在任何一种情况下,都没有为对象分配长期存储位置3,因此int &a实际上无法引用此对象.
"长期存储位置"表示将通过分配操作的位置.存储3的寄存器将在分配操作后立即被覆盖和重用,因此它在理论上甚至不符合目标int &a(实际上,int &a只能指代存储位置,而不是寄存器,无论如何).