2011-08-08 71 views
7

Xét đoạn mã sau:Chức năng-phạm vi constructor tĩnh của đối tượng ném một ngoại lệ

#include <iostream> 

struct X{ 
    X(){ 
     throw 0; 
    } 
}; 

void f(){ 
    static X x; 
} 

int main(){ 
    try { 
     f(); 
    } 
    catch(int) { 
     std::cout << "Caught first time" << std::endl; 
    } 
    try { 
     f(); 
    } 
    catch(int) { 
     std::cout << "Caught second time" << std::endl; 
    } 
} 

Kết quả của chương trình này là

Caught lần đầu tiên
Caught lần thứ hai

Vì vậy, nó được đảm bảo bởi các tiêu chuẩn mà các nhà xây dựng của một đối tượng tĩnh sẽ được gọi là hơn và hơn nữa cho il nó đã hoàn thành? Tôi không thể tìm thấy nơi trong tiêu chuẩn mà nó được đề cập, do đó, một trích dẫn hoặc một tham chiếu đến chương và câu được chào đón rất nhiều.

Hoặc có bất kỳ hành vi không xác định nào có liên quan đến ví dụ của tôi không?

Trả lời

14

Đảm bảo rằng việc xây dựng sẽ được thử miễn là không thành công.

Nó gây ra bởi những gì được nêu trong C++ 03 §6.7/4:

... Nếu một đối tượng như vậy được khởi sự kiểm soát thời gian đầu tiên đi qua tuyên bố của nó; một đối tượng như vậy được coi là khởi tạo khi hoàn thành việc khởi tạo nó. Nếu khởi tạo thoát bằng cách ném một ngoại lệ, khởi tạo không hoàn thành, do đó, nó sẽ được thử lại một lần nữa kiểm soát thời gian tiếp theo vào khai báo. Nếu điều khiển tái nhập vào khai báo (đệ quy) trong khi đối tượng đang được khởi tạo, hành vi là không xác định. [Ví dụ:

int foo(int i) 
{ 
    static int s = foo(2*i); // recursive call – undefined 
    return i+1; 
} 

--end dụ]

tôi sẽ lưu ý rằng gcc ném một ngoại lệ trong trường hợp nỗ lực khởi đệ quy, xem litb's related question như đối với nguồn của tôi.

+1

Cảm ơn. Bây giờ tôi biết về "tính năng" phức tạp của C++, tôi sẽ cố gắng lạm dụng nó. –

+0

@ Alexandre C .: tại sao không tạo Singleton! –

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