2012-10-14 26 views
7

kiểm tra: vs 2008, chế độ gỡ lỗiTại sao một hàm tạo bằng văn bản người dùng ảnh hưởng đến assembly được tạo ra? môi trường

mã kiểm tra là:

// a demo for return value 

class C 
{ 
public: 
    int value; 
    int value2; 
    int value3; 

    //C(int v=0): value(v) {}; 
}; 

C getC(int v) 
{ 
    C c1; 

    return c1; 
} 



int main() 
{ 
    C c1 = getC(10); 

    return 0; 
} 

và đầu ra asm là:

; 39 : C c1 = getC(10); 

push 10     ; 0000000aH 
lea eax, DWORD PTR $T2595[ebp] 
push eax 
call [email protected]@[email protected]@[email protected]   ; getC 
add esp, 8 
mov ecx, DWORD PTR [eax] 
mov DWORD PTR $T2594[ebp], ecx 
mov edx, DWORD PTR [eax+4] 
mov DWORD PTR $T2594[ebp+4], edx 
mov eax, DWORD PTR [eax+8] 
mov DWORD PTR $T2594[ebp+8], eax 
mov ecx, DWORD PTR $T2594[ebp] 
mov DWORD PTR _c1$[ebp], ecx 
mov edx, DWORD PTR $T2594[ebp+4] 
mov DWORD PTR _c1$[ebp+4], edx 
mov eax, DWORD PTR $T2594[ebp+8] 
mov DWORD PTR _c1$[ebp+8], eax 

Từ đầu ra asm, chúng ta có thể thấy các biên dịch tạo ra 2 đối tượng tạm thời.

Tuy nhiên, khi tôi xác định các nhà xây dựng như sau:

C(int v=0): value(v) {}; 

và biên dịch lại chương trình, đầu ra asm được trở thành:

; 39 : C c1 = getC(10); 

push 10     ; 0000000aH 
lea eax, DWORD PTR _c1$[ebp] 
push eax 
call [email protected]@[email protected]@[email protected]   ; getC 
add esp, 8 

Rõ ràng, trình biên dịch tối ưu hóa mã, và câu hỏi của tôi là:

Tại sao việc thêm hàm tạo bằng văn bản do người dùng tạo ảnh hưởng đến assembly được tạo ra quá nhiều?

+0

Trình biên dịch VC++ không thực hiện liên tục [Sao chép Elision] (http://en.wikipedia.org/wiki/Copy_elision). Bạn có thể thấy một ví dụ về điều đó. –

+0

Tôi đã chỉnh sửa để sử dụng cụm từ * user-writing * thay vì * explicit *, vì sau này hơi khó hiểu vì có từ khoá 'explicit' cho các hàm tạo (và đây không phải là) –

+8

Tôi thường không đề xuất để đọc quá nhiều vào mã assembly được tạo khi sử dụng Debug. Khi xây dựng Debug được sử dụng, trình biên dịch đảm bảo nó có thể thực hiện gỡ lỗi từng bước; điều này, đến lượt nó, có nghĩa là tối ưu hóa không phải lúc nào cũng được sử dụng. Nếu bạn muốn xem xét các hội đồng được tạo ra, tốt nhất làm như vậy trong xây dựng phát hành. – MicroVirus

Trả lời

1

Câu hỏi này là về sao chép elision và tối ưu hóa giá trị trả về trong C++.

Tôi đề nghị bạn không dành nhiều thời gian cho nó vì mã lắp ráp được tạo phụ thuộc vào trình biên dịch.

Sao chép sự bỏ bớt được định nghĩa trong tiêu chuẩn:

Khi tiêu chí nhất định được đáp ứng, một thực hiện được phép bỏ qua việc xây dựng sao chép/di chuyển của một đối tượng lớp, ngay cả khi sao chép/di chuyển constructor và/hoặc destructor cho đối tượng có tác dụng phụ. Trong những trường hợp như vậy, việc triển khai xử lý nguồn và đích của thao tác sao chép/di chuyển bị bỏ qua chỉ đơn giản là hai cách khác nhau tham chiếu đến cùng một đối tượng và sự hủy diệt đối tượng đó xảy ra sau đó khi hai đối tượng bị phá hủy mà không cần tối ưu hóa. sự bỏ bớt này hoạt động sao chép/di chuyển, được gọi là bản sao sự bỏ bớt, được cho phép trong các trường hợp sau (có thể được kết hợp để loại bỏ nhiều bản sao):

[...]

§12.8 [class.copy ]

Đã có câu hỏi bạn có thể tham khảo về luồng ngăn xếp, see here.

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