2010-09-16 38 views

Trả lời

12

Bạn nên sử dụng khối try/catch.

Khi những người khác đã trả lời, __try/__except là để bắt SEH (lỗi do cửa sổ tạo ra) không phải để bắt ngoại lệ chung.

Quan trọng nhất, __try__catch không được chạy trình phá hủy C++ hoặc giải phóng chính xác ngăn xếp khi ngoại lệ được ném.

Trừ trường hợp hiếm hoi, bạn không bao giờ nên cố gắng nắm bắt các ngoại lệ SEH.

EDIT: Vâng, tôi đã tích cực về điều này (đó là những gì tôi đã luôn luôn nói), nhưng @Hans nói rằng dường như có một trình chuyển đổi trình biên dịch bạn có thể sử dụng để thay đổi điều này. Tôi nghĩ rằng các tài liệu trên /EHa gây hiểu lầm hoặc ít nhất là không đầy đủ, về những gì xảy ra ở đây. Nếu ai đó tìm thấy tài liệu dứt khoát chứng minh điều này sai, tôi sẽ vui lòng xóa câu trả lời này.

Thậm chí nếu hóa ra điều này là sai, bạn vẫn nên sử dụng trycatch đơn giản vì chúng là tiêu chuẩn, trong khi __try__except thì không.

+0

Vì vậy, nó không thư giãn ngăn xếp? Điều đó có nghĩa rằng có thể là một ý tưởng tồi khi sử dụng '__try' /' __except' như một hệ thống báo cáo sự cố, trong khi nó có thể phục hồi từ một ngoại lệ trong khối 'try' /' catch'. –

+2

@David: Đúng vậy. '__try' và' __except' là đúng API dựa trên C/ABI. –

+0

Chỉ sử dụng tốt cho nó tôi đã nhìn thấy đã được đối phó với những gì lên đến lỗi trong Windows chính nó (chẳng hạn như những gì được sử dụng để xảy ra khi bạn cố gắng để sao chép một thiết bị). Có thể cho rằng chúng luôn là dấu hiệu của một nơi nào đó mà Windows đã bắt được ngoại lệ cho bạn và dịch nó thành một lỗi. (Cách họ làm việc rất khủng khiếp, và rất đặc biệt x86 ...) –

38

Hai số này là rất những thứ khác nhau. try/catch là các từ khóa C++ quen thuộc mà bạn biết. __try/__except được sử dụng để bắt ngoại lệ SEH. Các ngoại lệ được nâng lên bởi chính Windows, như là DivisionByZero hoặc AccessViolation. Nó cũng được mô tả trong các MSDN Library article cho nó.

Bạn cũng có thể sử dụng nó để bắt ngoại lệ C++ vì nó tận dụng tính năng Windows SEH. Tuy nhiên bạn không thể có được đối tượng ngoại lệ ném ra khỏi nó vì vậy sẽ có không bối cảnh nếu bạn thực sự muốn xử lý ngoại lệ. Đó là điên rồ. Cách tiếp cận số một là không bao giờ bắt được ngoại lệ SEH, chúng luôn luôn là tổng. Nếu bạn cần kết hôn thì hãy sử dụng _set_se_translator() để chuyển đổi ngoại lệ SEH thành ngoại lệ C++.

+3

+1 cho MSDN ref. –

6

__try/__except được thiết kế để gọi mã Win32 C không hỗ trợ ngoại lệ nhưng không sử dụng mã lỗi có cấu trúc/cơ chế xử lý. __try/__except sẽ dịch các lỗi C thành một khối ngoại lệ tương tự thành C++ try/catch.

Để biết thêm thông tin, hãy xem this MSDN article.

+0

+1 cho MSDN ref –

4

Chuẩn C++ sử dụng khối try/catch, vì vậy tôi khuyên bạn nên sử dụng chúng, nếu bạn cần cơ chế ngoại lệ "chuẩn", dựa trên thư viện chuẩn C++.

Tuy nhiên, nếu bạn dự định sử dụng Xử lý ngoại lệ có cấu trúc được cung cấp thông qua Windows SDK (xem here), sau đó sử dụng __try/__except.

+0

-1: STL hoàn toàn không liên quan gì đến xử lý ngoại lệ. –

+2

STL hoàn toàn liên quan đến xử lý ngoại lệ: std :: exception, là lớp cơ sở được đề xuất cho các ngoại lệ, ngay cả khi nó không bắt buộc. –

+0

'std :: exception' không phải là một lớp STL. –

1

Khi bạn đã ném thứ gì đó, bạn không còn có nhiều lựa chọn về cách bắt nó. Nếu bạn ném ngoại lệ C++ (tức là, với throw), sau đó sử dụng try/catch. Nếu bạn ném ngoại lệ cho Windows (nghĩa là, với RaiseException), hãy sử dụng __try/__except. Cố gắng trộn chúng sẽ chỉ thêm rắc rối không cần thiết cho cuộc sống của bạn.

+3

Nhưng bạn không bao giờ nên ném các cửa sổ ngoại lệ vì chúng không giải phóng ngăn xếp. –

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