2014-09-04 12 views
5

Câu hỏi của tôi rất đơn giản, nếu tôi có đoạn mã sau trong C++:Là đúc nguyên thủy, tạo một đối tượng mới trong bộ nhớ?

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 sẽ tạo một đối tượng mới trong bộ nhớ đó là sẽ chia i1 tới và giao trên f hoặc đúc điều hành là bằng cách nào đó dịch (float)i2 trên bay và làm các devision với không thêm bộ nhớ cho đúc?

Ngoài ra, điều gì đang diễn ra với các trường hợp truyền yêu cầu kích thước khác nhau của các biến? (Ví dụ như từ phao sẽ tăng gấp đôi)

+0

Để truyền từ phao sang gấp đôi hoặc theo cách khác, bạn có thể tìm thấy một số thông tin hữu ích tại đó: http://stackoverflow.com/questions/16737615/how-is-actually-done-floating-point-conversion-double- to-float-or-float-to-doub – JBL

Trả lời

4

(float)i2 sẽ tạo một đối tượng mới trong bộ nhớ

Dàn diễn viên tạo ra một đối tượng tạm thời, mà sẽ có lưu trữ riêng của mình. Điều đó không nhất thiết phải trong ký ức; một giá trị số học nhỏ như thế này có khả năng được tạo ra và được sử dụng trong một thanh ghi.

Ngoài ra, điều gì xảy ra với các trường hợp truyền yêu cầu các kích thước biến khác nhau?

Vì đối tượng mới được tạo, không quan trọng liệu chúng có kích thước và biểu diễn khác nhau hay không.

1

Nó phụ thuộc vào việc triển khai trình biên dịch và kiến ​​trúc máy. Trình biên dịch có thể sử dụng thanh ghi CPU cho các biến tạm thời, và nó cũng có thể sử dụng bộ nhớ ngăn xếp nếu cần thiết. Nghiên cứu đầu ra mức lắp ráp của trình biên dịch sẽ cho bạn biết nó làm gì trong một trường hợp cụ thể.

1

Giá trị của chuyển đổi có thể được lưu trữ trong bộ nhớ hoặc trong sổ đăng ký. Điều đó phụ thuộc vào phần cứng và trình biên dịch và tùy chọn biên dịch của bạn. Xem xét kết quả của biên dịch đoạn mã của bạn với g++ -O0 -c -g cast_code.cpp trên gcc 64 bit Cygwin:

[...] 
    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) 
    [...] 

Các ints được chuyển vào stack, và sau đó chuyển đổi sang nổi được lưu trữ trong thanh ghi mmx. Đối tượng mới? Có thể tranh cãi; trong bộ nhớ: thay vì không (tùy thuộc vào bộ nhớ là gì; đối với bộ nhớ của tôi nên địa chỉ).

Nếu chúng ta chỉ thị cho trình biên dịch để lưu trữ đúng cách các biến (ví dụ như để tránh các vấn đề chính xác với các thanh ghi chính xác hơn), chúng tôi nhận được như sau:

g++ -O0 -c -g -ffloat-store cast_code.cpp kết quả trong

// 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) 

Đó là hơi đau đớn khi thấy cách i1 được chuyển từ thanh ghi đến bộ nhớ ở 27 và sau đó quay lại thanh ghi ở 36 để phân chia có thể được thực hiện ở 3b.

Dù sao, hy vọng sẽ hữu ích.

+0

Cảm ơn rất hữu ích –

Các vấn đề liên quan