C++ Chuẩn khẳng định sau đây về việc thực hiện các std::call_once
với chức năng mà ném ngoại lệ (§30.4.4.2/2):Ném một ngoại lệ từ std :: call_once
2/Tác dụng: An thực hiện call_once mà không gọi func của nó là một thực thi thụ động. Việc thực thi call_once gọi hàm func của nó là một thực thi hoạt động. Một thực thi hoạt động sẽ gọi INVOKE (DECAY_- COPY (std :: forward (func)), DECAY_COPY (std :: forward (args)) ...). Nếu một cuộc gọi đến func ném một ngoại lệ thì việc thực hiện là ngoại lệ, nếu không nó sẽ trở lại. Một thực thi đặc biệt sẽ truyền bá ngoại lệ cho người gọi call_once. Trong số tất cả các lệnh gọi hàm call_once đối với bất kỳ once_flag cụ thể nào: tối đa là một lệnh thực thi trả về; nếu có một thực thi trả về, nó sẽ là thực thi hoạt động cuối cùng; và chỉ có các thực thi thụ động nếu có thực thi trả về. [Lưu ý: thực thi thụ động cho phép các luồng khác quan sát một cách đáng tin cậy các kết quả được tạo ra bởi thực thi trả về trước đó. - cuối note]
Tôi đang sử dụng Visual Studio 2012 và chạy đoạn mã sau:
void f(){
throw std::exception("Catch me!");
}
int main(int argc, char* argv[]){
once_flag flag;
try{
call_once(flag, f);
} catch(const std::exception& e){
cout << e.what() << endl;
}
return 0;
}
kết quả của tôi là: mã trong khối catch chạy và in thông điệp, nhưng khi chương trình tồn tại tôi nhận được một cuộc gọi đến abort()
và được thông báo sau in để cout:
... \ mutex.c (38) mutex bị phá hủy trong khi bận rộn
Điều này có nghĩa vụ phải xảy ra không?
Không, đó là lỗi, chương trình sẽ hoạt động tốt (mặc dù bạn đang sử dụng hàm tạo không chuẩn cho 'std :: exception', trong ISO C++ bạn chỉ có thể mặc định xây dựng' std :: exception', nguyên nhân Các vấn đề về tính di động thường xuyên khi người dùng MSVC kiểm tra lỗi có nghĩa là biên dịch trên các triển khai khác) –