【问题标题】:Is primitive casting, creates a new object in memory?原始铸造是在内存中创建一个新对象吗?
【发布时间】:2014-09-04 12:23:43
【问题描述】:

我的问题很简单,如果我在 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 并分配给fcasting 运算符以某种方式即时翻译(float)i2并且在没有额外内存的情况下进行设计?

此外,在转换需要不同大小的变量的情况下会发生什么? (例如从浮点数到双精度数)

【问题讨论】:

标签: c++ memory casting


【解决方案1】:

(float)i2 是否要在内存中创建一个新对象

演员表创建了一个临时对象,该对象将拥有自己的存储空间。那不一定在内存中。像这样的小算术值很可能会在寄存器中创建和使用。

另外,对于强制转换需要不同大小的变量的情况是怎么回事?

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

【讨论】:

    【解决方案2】:

    这取决于编译器实现和机器架构。编译器可以将 CPU 寄存器用于临时变量,也可以在需要时使用堆栈内存。研究编译器的汇编级输出将告诉您它在特定情况下的作用。

    【讨论】:

      【解决方案3】:

      转换的值可以存储在内存或寄存器中。这取决于您的硬件和编译器以及编译选项。考虑在 cygwin 64 位 gcc 上使用 g++ -O0 -c -g cast_code.cpp 编译 sn-p 的结果:

        [...]
        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 处执行除法,这有点痛苦。

      无论如何,希望对您有所帮助。

      【讨论】:

      • 感谢您的帮助
      猜你喜欢
      • 1970-01-01
      • 2021-06-08
      • 2020-01-17
      • 1970-01-01
      • 1970-01-01
      • 2017-07-08
      • 1970-01-01
      • 2015-10-01
      相关资源
      最近更新 更多