2010-06-14 35 views
17

Được tạo tạm thời như là một phần của một đối số cho một cuộc gọi hàm được bảo đảm ở lại cho đến khi hàm được gọi kết thúc, ngay cả khi tạm thời không được chuyển trực tiếp đến hàm?Khi nào các thời gian được tạo ra như một phần của một cuộc gọi chức năng bị hủy?

Có hầu như không có cơ hội đó là chặt chẽ, vì vậy đây là một ví dụ:

class A { 
public: 
    A(int x) : x(x) {printf("Constructed A(%d)\n", x);} 
    ~A() {printf("Destroyed A\n");} 

    int x; 
    int* y() {return &x;} 
}; 

void foo(int* bar) { 
    printf("foo(): %d\n", *bar); 
} 

int main(int argc, char** argv) { 
    foo(A(4).y()); 
} 

Nếu A(4) được chuyển trực tiếp đến foo nó chắc chắn sẽ không bị hủy diệt cho đến sau khi cuộc gọi foo kết thúc, nhưng thay vào đó tôi đang gọi một phương pháp tạm thời và mất mọi tham chiếu đến nó. Tôi theo bản năng nghĩ rằng tạm thời A sẽ bị phá hủy trước khi foo thậm chí bắt đầu, nhưng thử nghiệm với GCC 4.3.4 cho thấy nó không phải là; đầu ra là:

Xây dựng A (4)
foo(): 4
Destroyed Một

Câu hỏi đặt ra là, được hành vi của GCC được bảo đảm bởi spec? Hoặc là một trình biên dịch được phép hủy bỏ tạm thời A trước khi gọi tới số foo, đánh dấu con trỏ đến thành viên mà tôi đang sử dụng?

Trả lời

17

Đối tượng tạm thời tồn tại cho đến khi kết thúc biểu thức đầy đủ mà chúng được tạo ra.

Trong ví dụ của bạn, đối tượng A tạo ra bởi A(4) sẽ tồn tại ít nhất cho đến khi biểu thức kết thúc ngay sau khi trở về từ cuộc gọi đến foo().

Hành vi này được đảm bảo bằng các tiêu chuẩn ngôn ngữ:

đối tượng tạm thời bị phá hủy như là bước cuối cùng trong việc đánh giá đầy đủ biểu thức (1.9) mà (giải nghĩa từ vựng) chứa các điểm mà họ đã tạo ra. Điều này đúng ngay cả khi đánh giá đó kết thúc bằng việc ném một ngoại lệ (C++ 03 §12.2/3).

Thời gian tạm thời có thể được kéo dài bằng cách liên kết tham chiếu đến nó (trong trường hợp đó là thời gian kéo dài cho đến khi kết thúc tham chiếu) hoặc bằng cách khởi tạo trong bộ khởi tạo của hàm khởi tạo danh sách (trong trường hợp này, tuổi thọ của nó được kéo dài cho đến khi đối tượng được xây dựng được xây dựng hoàn chỉnh).

+0

tạo ảnh vui nhộn Nhờ bạn và Jerry cho việc tìm kiếm các tài liệu tham khảo trong spec, tôi đã khó khăn khi tìm nó –

2

Tạm thời kéo dài cho đến khi kết thúc biểu thức nó là một phần của - trong trường hợp này là một cuộc gọi hàm.

-1

Thời gian tồn tại của đối tượng tạm thời của bạn A(4) sẽ kéo dài đủ để gọi y()

Bộ nhớ lưu ý trong sự trở lại của y() là không đáng tin cậy, phụ thuộc vào luồng và phân bổ nó có thể được phân bổ lại và giá trị thay đổi trước hãy gọi tới số foo() để sử dụng.

+0

Hmmm , dường như MSVC đang cho tôi một câu trả lời không chuẩn, tốt để học tiêu chuẩn. –

5

§12.2/3: "Các đối tượng tạm thời bị hủy khi bước cuối cùng trong việc đánh giá biểu thức đầy đủ (1.9) (từ từ) chứa điểm mà chúng được tạo."

IOW, bạn đang an toàn -.. Đối tượng A phải không bị hủy diệt cho đến sau foo lợi nhuận

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