Đoạn mã dưới đây tạo ra một tham chiếu lơ lửng như có thể thấy trong cảnh báo được trình biên dịch phát ra và thực tế là hàm hủy đối tượng A
trong hàm g()
được gọi trước khi hàm trả về. Người ta cũng có thể xác minh rằng trong main()
sau khi "sử dụng ngăn xếp", tham chiếu trả lại có rác, ít nhất là trong bản dựng gỡ lỗi. Nhưng tôi không thể tái tạo cùng một hành vi trong bản phát hành bản phát hành. Tại sao vậy? Loại tối ưu hóa trình biên dịch đang làm gì ở đây để tạo ấn tượng rằng tham chiếu r
là Ok?Điều gì xảy ra với đoạn mã bên dưới trong bản dựng bản phát hành?
#include <iostream>
struct A{
A(int i) : i(i) { std::cout << "Ctor\n"; }
A(const A& a) { i = a.i; std::cout << "Copy ctor\n"; }
~A() { std::cout << "Dtor\n"; }
int i;
};
A& g(int i) { A x(i); return x; }
int main()
{
const A& r = g(1);
std::cout << "Using the stack\n";
std::cout << r.i << '\n'; // r.i has garbage in debug, but not in a release build.
}
PS. Tôi sẽ tranh luận chống lại NRVO, vì hàm không trả về một đối tượng A
.
Chỉnh sửa: Trả lời Mark Tolonen. Thậm chí nếu tôi bao gồm các biểu thức sau const A& r = g(1);
việc phát hành xây dựng không hiển thị rác trong std::cout << r.i << '\n';
std::cout << "Using the stack ...................................................................................................................\n";
std::cout << "Using the stack ...................................................................................................................\n";
std::cout << "Using the stack ...................................................................................................................\n";
std::cout << "Using the stack ...................................................................................................................\n";
Hành vi không xác định là không xác định ... (kết quả đầu ra 1 cho tôi trong cả bản phát hành và gỡ lỗi) – jrok
**** VS2010 **** – WaldB
Đã tháo gỡ được kiểm tra. Nó được tối ưu hóa, hoặc trong đăng ký hoặc sử dụng ngay lập tức. – Immueggpain