我的问题很简单,如果我在C ++中有以下代码:
int main(int argc, const char * argv[])
{
int i1 = 5;
int i2 = 2;
float f = i1/(float)i2;
std::cout << f << "\n";
return 0;
}
(float)i2
是否会在内存中创建一个新对象,该对象下一步将i1
并在f
上分配,或者投射运算符会以某种方式进行翻译(float)i2
在飞行中并且没有额外的内存用于投射吗?
此外,铸造需要不同大小的变量的情况如何? (例如从浮动到双倍)
答案 0 :(得分:4)
(float)i2
是否要在内存中创建新对象
强制转换会创建一个临时对象,该对象将拥有自己的存储空间。这不一定在记忆中;像这样的小算术值可能会在寄存器中创建和使用。
此外,如果投射需要不同大小的变量?
由于创建了一个新对象,它们是否具有不同的大小和表示并不重要。
答案 1 :(得分:1)
这取决于编译器实现和机器架构。编译器可以将CPU寄存器用于临时变量,如果需要,它还可以使用堆栈存储器。研究编译器的汇编级输出会告诉你它在特定情况下的作用。
答案 2 :(得分:1)
转换的值可以存储在存储器或寄存器中。这取决于您的硬件和编译器以及编译选项。考虑在cygwin 64位gcc上使用g++ -O0 -c -g cast_code.cpp
编译代码段的结果:
[...]
14: c7 45 fc 05 00 00 00 movl $0x5,-0x4(%rbp)
int i2 = 2;
1b: c7 45 f8 02 00 00 00 movl $0x2,-0x8(%rbp)
float f = i1/(float)i2;
22: f3 0f 2a 45 fc cvtsi2ssl -0x4(%rbp),%xmm0
27: f3 0f 2a 4d f8 cvtsi2ssl -0x8(%rbp),%xmm1
2c: f3 0f 5e c1 divss %xmm1,%xmm0
30: f3 0f 11 45 f4 movss %xmm0,-0xc(%rbp)
[...]
将整数移入堆栈,然后转换为存储在mmx寄存器中的浮点数。新物品?有争议的;在内存中:而不是(取决于什么是内存;对我而言,内存应该是可寻址的。)
如果我们指示编译器正确存储变量(例如为了避免更精确的寄存器的精度问题),我们得到以下结果:
g++ -O0 -c -g -ffloat-store cast_code.cpp
会产生
// identical to above
14: c7 45 fc 05 00 00 00 movl $0x5,-0x4(%rbp)
int i2 = 2;
1b: c7 45 f8 02 00 00 00 movl $0x2,-0x8(%rbp)
float f = i1/(float)i2;
// same conversion
22: f3 0f 2a 45 fc cvtsi2ssl -0x4(%rbp),%xmm0
// but then the result is stored on the stack.
27: f3 0f 11 45 f4 movss %xmm0,-0xc(%rbp)
// same for the second value (which undergoes an implicit conversion).
2c: f3 0f 2a 45 f8 cvtsi2ssl -0x8(%rbp),%xmm0
31: f3 0f 11 45 f0 movss %xmm0,-0x10(%rbp)
36: f3 0f 10 45 f4 movss -0xc(%rbp),%xmm0
3b: f3 0f 5e 45 f0 divss -0x10(%rbp),%xmm0
40: f3 0f 11 45 ec movss %xmm0,-0x14(%rbp)
看到i1如何在27处从寄存器移动到存储器然后再返回36处的寄存器有点痛苦,以便可以在3b处执行除法。
无论如何,希望有所帮助。