2014-09-04 17 views
5

我的問題很簡單,如果我在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要在內存旁邊去devide i1和分配上f鑄造運算符來創建新的對象是不知何故翻譯(float)i2在飛行中,並執行沒有額外的內存鑄造的devision?

此外,鑄造需要不同大小的變量的情況是怎麼回事? (例如,從浮到雙)

+0

對於從float轉換爲double或其他方式,您可能會發現一些有用的信息:http://stackoverflow.com/questions/16737615/how-is-actually-done-floating-point-conversion-double-浮動或浮動到雙倍 – JBL 2014-09-04 12:29:29

回答

4

(float)i2會在內存中

鑄創建一個臨時的對象,這將有自己的存儲創建一個新的對象。這不一定在記憶中;像這樣的小算術值可能會被創建並用於寄存器中。

此外,鑄造需要不同大小的變量的情況是怎麼回事?

由於創建了一個新對象,它們是否具有不同的大小和表示形式並不重要。

1

這取決於編譯器實現和機器體系結構。編譯器可以使用CPU寄存器作爲臨時變量,如果需要,它也可以使用堆棧存儲器。研究編譯器的彙編級輸出會告訴你它在特定情況下的功能。

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移動到存儲器27,然後返回到寄存器36,從而可以在3b執行分割。

無論如何,希望有所幫助。

+0

非常感謝您的幫助 – 2014-09-04 12:53:11