是基元铸造,在内存中创建一个新对象
Is primitive casting, creates a new object in memory?
我的问题很简单,如果我在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
并在没有额外内存用于铸造的情况下进行设计?
此外,铸造需要不同大小的变量的情况是怎么回事?(例如从浮动到双)
(float)i2
将在内存中创建一个新对象吗
强制转换将创建一个临时对象,该对象将有自己的存储空间。这不一定在记忆中;像这样的小算术值很可能会被创建并在寄存器中使用。
此外,铸造需要不同大小的变量的情况是怎么回事?
既然创建了一个新对象,那么它们是否具有不同的大小和表示方式并不重要。
它取决于编译器实现和机器体系结构。编译器可以为临时变量使用CPU寄存器,如果需要,也可以使用堆栈内存。研究编译器的汇编级输出可以告诉你它在特定情况下会做什么。
转换的值可以存储在内存或寄存器中。这取决于您的硬件、编译器和编译选项。考虑一下在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)
[...]
int被移到堆栈上,然后转换为浮点值,这些浮点值存储在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处执行除法,这有点痛苦。
不管怎样,希望能有所帮助。
相关文章:
- 为什么我不能将一个对象push_back到属于另一个类的对象向量中?
- 在他自己的方法中,有可能将一个对象取消引用到另一个对象吗
- 从多个源构造一个对象,包括一个对象向量
- 为什么C++在将一个对象复制到另一个对象时需要对这两个对象进行低级常量限定
- 检查哪个对象调用了另一个对象的对象方法
- C++ 如何在将新对象分配给另一个对象时创建新对象
- 如何处理从一个对象传递到另一个在C++中具有公共抽象类的对象的消息
- 我有一个对象,它将在整个程序的持续时间内实例化,但一个类成员不会,我应该动态分配它吗?
- 包装一个对象并假装它是一个 int
- 为什么我可以在不重载 "=" 运算符的情况下将一个对象分配给另一个对象?
- 如何在qt中将信号和插槽与另一个对象连接 --解决了
- 如何使用函数将一个对象的输入复制到另一个对象中
- 选择一个元素而不是一个对象的数组的原因
- 为什么我可以使用 memcpy 将一个对象变量复制到另一个对象变量
- 如何将包含另一个对象向量的对象保存到文件中,并使用C++中的二进制文件从文件中读回?
- 我重载了 << 和 = 运算符。为什么当我将一个对象分配给另一个对象并尝试打印它时,我会被打印出来?
- 打印对象的映射,其中另一个对象作为键
- 如何通过另一个对象中的命令正确地从一个对象返回数据
- 为什么将两个对象分配给另一个对象后,两个对象不一样?
- 绘制一个对象,比较模具缓冲区的两个不同值