2011-09-29 6 views
6

thể trùng lặp:
What is the difference between r-value references and l-value references? (CodeGen)C++: Tham chiếu giá trị R ở cấp độ kỹ thuật (ASM) là gì?

tôi đã tự hỏi, bất cứ ai có thể giải thích những gì tài liệu tham khảo R-Value là về mặt kĩ thuật? Điều đó có nghĩa là: Điều gì xảy ra ở cấp độ lắp ráp khi các tham chiếu R-Value được tạo ra.

Đối với một thử nghiệm nhỏ để xem những gì xảy ra bên trong tôi đã viết đoạn mã sau:

char c = 255; 
char &c2 = c; 
char &c3 = std::move(c); 

Tôi biết nó làm cho không có ý nghĩa để tạo ra một tài liệu tham khảo R-Value để 'c', nhưng chỉ vì lợi ích của thử nghiệm tôi đã làm nó anyway, để xem những gì nó làm. Và đây là kết quả:

unsigned char c = 255; 
    mov   byte ptr [c],0FFh 
unsigned char &c2 = c; 
    lea   eax,[c] 
    mov   dword ptr [c2],eax 
unsigned char &&c3 = std::move(c); 
    lea   eax,[c] 
    push  eax 
    call  std::move<unsigned char &> (0ED1235h) 
    add   esp,4 
    mov   dword ptr [c3],eax 

Tôi đến nay không có chuyên gia nhưng tôi cho rằng, trong trường hợp này, 'c3' thường là tham chiếu đến 'c'.

Nếu tôi ràng buộc tham chiếu R-Giá trị trực tiếp đến một tạm thời (char & & c3 = 255), các bit cuối cùng của những thay đổi lắp ráp như vậy:

unsigned char &&c3 = 255; 
    mov   byte ptr [ebp-29h],0FFh 
    lea   eax,[ebp-29h] 
    mov   dword ptr [c3],eax 

Từ vẻ của sự thay đổi này, tôi giả rằng c3 vẫn thực sự là một tham chiếu đến một số vị trí bộ nhớ chứa giá trị 255. Vì vậy, nó là một tham chiếu thường xuyên - giá trị không được sao chép/gán cho c3. Điều này có đúng không?

Có ai có thể nói nếu giả định của tôi là chính xác hoặc nếu tôi hoàn toàn không theo dõi? Cho đến bây giờ, tôi luôn luôn nghĩ đến các tham chiếu R-Value để khớp với một chữ ký hàm/phương thức (có thể là di chuyển-ctor) khi nói đến độ phân giải gọi, để coder biết cách xử lý dữ liệu được cung cấp (cho một ctor di chuyển) sẽ di chuyển dữ liệu thay vì sao chép dữ liệu).

Để bảo vệ nỗ lực khá ngu ngốc này, tôi vừa trình bày: Tôi không định xoay quanh mã của tôi ở cấp độ asm, tôi chỉ muốn biết các tham chiếu R-Value khác biệt so với phần còn lại tât cả nhưng năm thang đo.

Mọi thông tin chi tiết và giải thích đều được hoan nghênh!

Cảm ơn!

+3

Ở mức lắp ráp (chưa được tối ưu hóa), Giá trị R là một phiên bản của đối tượng, giống như Giá trị L, tham chiếu hoặc "giá trị". Giá trị R chỉ đơn giản là cho _compiler_ có chức năng sử dụng để sao chép/xây dựng. Điều này tương tự như cách một tham chiếu trong một đối tượng hoặc tham số thực sự chỉ là một con trỏ ở cấp độ assembly, nhưng được xử lý khác nhau _by compiler_. –

+1

Lưu ý rằng 'c3' là tham chiếu giá trị l, không phải giá trị r. – avakar

+3

"Kỹ thuật". Bạn tiếp tục sử dụng từ đó. Tôi không nghĩ rằng nó có nghĩa là những gì bạn nghĩ rằng nó có nghĩa là. –

Trả lời

8

Điều gì sẽ xảy ra ở cấp trình lắp ráp khi các tham chiếu giá trị R được tạo.

Bất cứ điều gì cần thiết để duy trì ngữ nghĩa cấp cao. Trình biên dịch nào chính xác phụ thuộc vào những gì nhà cung cấp trình biên dịch nghĩ là một ý tưởng hay. Hội không có khái niệm về giá trị, giá trị hoặc tham chiếu, vì vậy hãy ngừng tìm kiếm chúng. Bật các tối ưu hóa và mã bạn đang xem có thể sẽ thay đổi (hoặc có thể ngừng tồn tại, nếu các biến không được sử dụng).

Tôi chỉ muốn biết được những khác biệt về mặt kỹ thuật R-Value được giới thiệu so với phần còn lại đã tồn tại trong những năm này.

Tham chiếu giá trị cho phép ngữ nghĩa di chuyển và lần lượt cho phép các cơ hội tối ưu hóa quan trọng.Các tiêu chuẩn không nói "oh, đây là những rvalue refs, và đó là cách bạn nên thực hiện chúng trong hội đồng". Thực hiện thậm chí có thể không sản xuất lắp ráp.

4

Trước khi tối ưu hóa, tham chiếu tồn tại dưới dạng con trỏ có chứa địa chỉ của đối tượng bị ràng buộc.

Nhưng trình biên dịch sẽ cố gắng hết sức để tối ưu hóa nó. Nội tuyến đặc biệt có thể gây ra tất cả việc sử dụng tham số tham chiếu bên trong một hàm nhỏ được thay thế bằng cách sử dụng trực tiếp thanh ghi có chứa giá trị của đối tượng bị ràng buộc.

6

Tham chiếu Rvalue không khác nhau về cấp độ asm - nó có thể chính xác giống như refernces thông thường (phụ thuộc vào cách trình biên dịch nhìn thấy nó). Sự khác biệt chỉ tồn tại ở cấp độ C++ langiage. Tham chiếu giá trị r thông tin đang mang là đối tượng được tham chiếu là tạm thời và bất kỳ ai nhận được đối tượng đó đều miễn phí sửa đổi nó. Thông tin về vị trí đối tượng có thể được chuyển chính xác giống như với các tham chiếu thông thường (trình biên dịch có thể cố gắng tối ưu hóa nó một cách khác nhau, nhưng đó là vấn đề nội bộ của trình biên dịch).

Sự khác biệt giữa tham chiếu giá trị r và tham chiếu giá trị l không phải là giá trị l sẽ tự động được gán cho tham chiếu giá trị l (do đó ngăn ngừa sửa đổi vô tình), trong khi biểu thức r giá trị sẽ chuyển đổi sang cả hai (với giá trị r ref. preffered), cho phép di chuyển ngữ nghĩa và các cuộc gọi thông thường nếu di chuyển ngữ nghĩa không được hỗ trợ. std :: di chuyển không làm gì khác ngoài việc cho phép tự động truyền các giá trị l vào các tham chiếu r giá trị.

0

khái niệm tham chiếu rvalue có thể được mô tả hoàn toàn ở cấp độ C++, không cần phải đọc Mã lắp ráp cho điều này. Bạn chỉ cần có một số lớp C++ tối thiểu phân bổ tài nguyên nội bộ, và "ăn cắp" tài nguyên tham chiếu rvalue bởi một đối tượng khác là hiển nhiên. Giống như trong lớp remote_integer từ bài viết cổ điển này: http://blogs.msdn.com/b/vcblog/archive/2009/02/03/rvalue-references-c-0x-features-in-vc10-part-2.aspx Phiên dịch hội cho mã này khá đơn giản, nhưng sự khác biệt được nhìn thấy trong mã C++. Về các kiểu đơn giản như char - chúng có thể được sử dụng để hủy bỏ một số tính năng cú pháp tham chiếu rvalue, nhưng không có sence để sử dụng tham chiếu rvalue trên loại đó - cả trên C++ và Assembly. Vì vậy, nếu bạn không thấy bất kỳ lợi thế nào khi sử dụng char & & c trong C++, thì cũng không có gì thú vị trong Assembly.