Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 是原语转换,在内存中创建一个新对象?_C++_Memory_Casting - Fatal编程技术网

C++ 是原语转换,在内存中创建一个新对象?

C++ 是原语转换,在内存中创建一个新对象?,c++,memory,casting,C++,Memory,Casting,我的问题很简单,如果我有以下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; } int main(int argc,const char*argv[] { int i1=5; int i2=2; 浮点数f=i1/(浮点

我的问题很简单,如果我有以下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;
}
int main(int argc,const char*argv[]
{
int i1=5;
int i2=2;
浮点数f=i1/(浮点数)i2;
标准::cout
(float)i2
是否将在内存中创建新对象

强制转换创建一个临时对象,该对象将有自己的存储空间。这不一定在内存中;像这样的小算术值可能会被创建并在寄存器中使用

还有,铸造需要不同大小变量的情况是什么


由于创建了一个新对象,它们是否具有不同的大小和表示形式并不重要。

这取决于编译器实现和机器体系结构。编译器可以使用CPU寄存器作为临时变量,如果需要,还可以使用堆栈内存。研究编译器的汇编级输出将在特定的情况下,它可以做什么。< /P> < P>转换的值可以存储在内存中或登记器中。这取决于硬件和编译器和编译选项。考虑CygWin 64位GCC:

编译代码片段的结果:使用代码> G++-O0-C-GasCasyCalp.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存储cast\u 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处执行除法,有些痛苦


无论如何,希望这能有所帮助。

对于从浮动到双精度或其他方式的铸造,您可以在那里找到一些有用的信息:谢谢,这非常有用