考虑这个例子:
int a = 5;
int b = 10;
int c = a + b; //where is the value of (a+b) stored?
a = a + b; //how about now?
我的理解是临时对象的处理方式类似于新的局部变量,即它们位于堆栈顶部。但是在我的例子的第3行中,将(a + b)直接提升到c?还是复制?它会在第4行复制到?
的位置编辑:修复语法错误。 为什么我关心?因为我正在寻找一般答案,例如当我不使用int而是使用大对象或者可能是堆对象的包装器时。
答案 0 :(得分:4)
允许C ++编译器按照" as-if"编译代码。规则:也就是说,您编写的源代码描述了程序的意图,而不是编译代码。
因此,编译器可能会将您的代码重构为
int b = 10;
int c = 15;
int a = 15;
或者,根据变量的任何后续使用情况,它可能会忽略它们。最后,请注意堆栈是一种实现概念,而不是语言概念。除了几个C ++标准库函数之外,C ++标准本身根本没有提到堆栈。
答案 1 :(得分:4)
为什么要关心?为什么要存放在任何地方?代码
a = a + b;
将使编译器创建与您期望的行为相似的代码,在您首先需要知道的所有内容中。可能是中间值只存储在某个cpu寄存器中,可能是它没有存储在任何地方,可能是编译器会执行与此相同的操作:
int temp = a + b;
a = temp;
另一方面,如果您确实关心编译器对代码的作用,则需要查看其输出。编译器是相当复杂的野兽,做出一般假设通常是错误的。这是检查编译器输出的一个很棒的工具:https://godbolt.org/
答案 2 :(得分:0)
对于内在类型,无所谓;可观察的行为很容易确定,并且所有类型的优化都会发生。 但是对于UDT来说,长话故事。如果临时值被值抓住:
如果通过引用抓取UDT临时值,它的生命周期将扩展到引用的范围,它将被视为普通左值。不会发生任何复制/移动。当参考死亡时会发生破坏。